1. 程式人生 > >Floyd傳遞閉包的應用 POJ 3660

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;
}