POJ 3660-Cow Contest(Floyd+传递闭包)

Cow Contest

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 20521 Accepted: 11372

Description

N (1 ≤ N ≤ 100) cows, conveniently numbered 1…N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors.

The contest is conducted in several head-to-head rounds, each between two cows. If cow A has a greater skill level than cow B (1 ≤ A ≤ N; 1 ≤ B ≤ N; A ≠ B), then cow A will always beat cow B.

Farmer John is trying to rank the cows by skill level. Given a list the results of M (1 ≤ M ≤ 4,500) two-cow rounds, determine the number of cows whose ranks can be precisely determined from the results. It is guaranteed that the results of the rounds will not be contradictory.

Input

  • Line 1: Two space-separated integers: N and M
  • Lines 2…M+1: Each line contains two space-separated integers that describe the competitors and results (the first integer, A, is the winner) of a single round of competition: A and B

Output

  • Line 1: A single integer representing the number of cows whose ranks can be determined

Sample Input

5 5
4 3
4 2
3 2
1 2
2 5

Sample Output

2

题目链接

N(1≤N≤100)头母牛,方便地编号1…N,正在参加编程竞赛。众所周知,有些母牛的编码要好于其他母牛。每头母牛都有一定的恒定技能等级,这在竞争者中是独一无二的。

比赛分几个头对头进行,每回合在两头母牛之间进行。如果母牛A的技能水平高于母牛B(1≤A≤N; 1≤B≤N; A≠B),那么母牛A总是会击败母牛B。

农夫约翰试图按技能水平对母牛进行排名。给出一个清单,列出两轮M(1≤M≤4,500)M的结果,确定可以从结果精确确定其等级的母牛的数量。可以保证回合的结果不会矛盾。

输入值

*第1行:两个以空格分隔的整数:N和M
*第2…M + 1行:每行包含两个以空格分隔的整数,它们描述了单轮比赛的竞争者和结果(第一个整数A是获胜者):A和B

输出量

*第1行:一个整数,代表可以确定其等级的母牛的数量

样本输入

5 5
4 3
4 2
3 2
1 2
2 5
样本输出

2

解题思路:这道题是POJ上的题,考察的是一个传递闭包和Floyd,给出的数据是输入n和m,表示一共有n头牛,一共有m组比赛,接下来是m行,每行输入两个母牛的编号,表示前面的母牛战胜了后面的母牛。最后要求输出的能确定排名的母牛数量,要确定排名,就是说有n头牛,如果这头牛能打败的和不能打败的相加==n-1,则说明能确定排名,这是一个传递闭包问题,我们先用Floyd算法解决传递闭包再处理排名,开一个存储关系的数组map,如果输入 5 4 则map[5][4]=1,说明5号牛能打败4号牛,借助一个中间点J,如果 I 号母牛能打败 J 号母牛, J 号母牛能打败 K号母牛,则说明 I 号母牛能打败K号母牛,处理完闭包后,处理排名,用两个for循环(母牛两两比较,如果比较到其中一个 两母牛没有关系则退出内循环,如果能走完内循环则ans++,此处所说的关系包含打败和被打败),最后输出ans即可。AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int _max=105;
int map[_max][_max];//关系数组
int n,m,a,b;
int main()
{
	void floyd();
	memset(map,0,sizeof(map));
	cin>>n>>m;
	while(m--)
	{
		cin>>a>>b;
		map[a][b]=1;
	}
    floyd();
    int ans=0;
    int i,j;
    for(i=1;i<=n;i++)
    {
    	for(j=1;j<=n;j++)
    	  if(i!=j)
            if(map[i][j]==0&&map[j][i]==0)//如果没有关系退出内循环
              break;
        if(j>n)//如果能走出内循环则说明最后关系数量达到了n-1(因为i!= j 所以内循环严格来说有n-1次判断关系)
		  ans++;      
	}
	cout<<ans<<endl;
	return 0;
}
void floyd()//通过Floyd处理传递闭包
{
	for(int j=1;j<=n;j++)
	  for(int i=1;i<=n;i++)
	    for(int k=1;k<=n;k++)
	      if(map[i][j]&&map[j][k])
	        map[i][k]=1;
}
发布了34 篇原创文章 · 获赞 0 · 访问量 795

猜你喜欢

转载自blog.csdn.net/aezakmias/article/details/104619407