Floyd传递闭包的应用 POJ 3660

题目链接:http://poj.org/problem?id=2240

题解:应用Floyd的算法,不求路径,而是标记任意两点之间是否可达。然后根据出度+入度是否等于顶点数-1来判断该顶点在所有顶点中的排名是否确定。因为如果出度+入度是否等于顶点数-1,则其他顶点到与该顶点的关系则都确认了,所以也就可以确认该点的排名

AC代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#define inf 0x7fffffff
#define MAX_V 105

using namespace std;

int d[MAX_V][MAX_V];
int n,m;

void floyd()
{
	for(int k = 1; k <= n; k++)//k必须在外层,根据k的变动不停地松弛i、j之间的最短路,ij可以重复遍历,但k不能 
	{
		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= n; j++)
			{
				d[i][j] = d[i][j] || (d[i][k] && d[k][j]);//传递闭包 
			} 
		}
	}
}

int main()
{
	int a,b;
	while(cin>>n>>m)
	{
		memset(d,0,sizeof(d));
		for(int i = 0; i < m; i++)
		{
			cin>>a>>b;
			d[a][b] = 1;
		}
		floyd(); 
		int ans = 0;
		for(int i = 1; i <= n; i++)
		{
			int num = 0;
			for(int j = 1; j <= n; j++)
			{
				if(i == j)	continue;
				if(d[i][j] || d[j][i])
					num++;		
			}
			if(num == n-1)//如果出度+入度=n-1则可以确定该牛的排名 
				ans++;
		} 
		cout<<ans<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/cutedumpling/article/details/81226400