POJ 3660 Cow Contest(Floyd)

Cow Contest
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

 

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 ≤ NA≠ 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,2,3……N标号,然后再给出A B就是A的等级比B高,要你求出确定顺序位置的元素个数。例子中2 和 5是确定位置的。

这道题,应该是会有好几种解法的,但是网络流传最多的就是floyd了,如果你想懂了的话,真的发现用floyd很简单。我们可以把它当成一个图,然后用floyd把可以相连的点的距离全都求出来,但是我们并不需要距离的这个值,我们需要的是他这种判断连通的功能。用两个数组in(入度),out(出度)(其实一个也行)初始化为0,然后开始遍历整个map,如果某两个点连通,比如map[ i ][ j ]连通,那么in[ j ]++,out[ i ]++。最后再来一次循环,走一次全部点,如果in[ i ] + out[ j ]等于n - 1的话,那么他的位置就是确定了的,cout++。最后输出cout就行了。

代码如下:

#include<stdio.h>
#define INF 0xfffffff
int map[105][105]={0};

void init()
{
	for(int i=1;i<=100;i++)
		for(int j=1;j<=100;j++)
		{
			if(i == j)
				map[i][j]=0;
			else
				map[i][j]=INF;
		}
}

void floyd_warshall(int n)  
{  
    int i, j, k;  
    for (k = 1; k <= n; k++)  
        for (i = 1; i <= n; i++)  
            for (j = 1; j <= n; j++)  
                if (map[i][k] + map[k][j] < map[i][j])  
                    map[i][j] = map[i][k] + map[k][j];     
}

int main()
{
	int n, m, a, b, cout, i, j;
	int in[105] = {0}, out[105] = {0};
	scanf("%d%d", &n, &m);
	init();
	while(m--)
	{
		scanf("%d%d", &a, &b);
		map[a][b] = 1;
	}
	floyd_warshall(n);
	cout = 0;
	for (i = 1; i <= n; i++)  
        for (j = 1; j <= n; j++)  
            if(map[i][j] != INF && i != j)  
            {
            	in[j]++;
            	out[i]++;
			} 
	for(i = 1; i <= n; i++)
		if(in[i] + out[i] == n - 1)
			cout++;
	printf("%d\n",cout);
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值