概念: ios
傳遞一種關係,例如 a//b b//c 則 a//c spa
從已知的初始關係中 推出最後全部對象之間的關係.net
初始時把全部有關係的標記爲1 即a[i][j] = 1code
而後用Floyd 推出最後的結果 則有關係的兩個對象被標記爲1對象
void Floyd() { for(int k=0; k<=n; ++k) for(int i=0; i<=n; ++i) for(int j=0; j<=n; ++j) a[i][j] = a[i][j] || (a[i][k] && a[k][j]); }
例題:POJ3660blog
題意:排序
n個牛打架 初始已知m個打架結果 求最後能肯定具體名次的牛 有幾個ci
開始就覺得是拓撲排序 而後一想。。並查集?get
行吧。。。在最短路專題 就是最短路把。。。博客
固然這題拓排和並查集也能作 https://blog.csdn.net/u010372095/article/details/45201653 請看大佬博客。。。
解析:
用Floyd肯定最後的關係後若是 一個牛戰勝了x個 被y個戰勝 且x+y == n-1 則 這個牛的名次則能夠肯定 想一下是否是呀
那麼。。。貼代碼了。。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int maxn = 110; int a[maxn][maxn]; int n,m; void Floyd() { for(int k=1; k<=n; ++k) for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) a[i][j] = a[i][j] || (a[i][k] && a[k][j]); } int main() { cin>> n >> m; mem(a,0); for(int i=0; i<m; ++i) { int u, v; cin>> u >> v; a[u][v] = 1; } Floyd(); int res = 0; for(int i=1; i<=n; ++i) { int ans = 0; for(int j=1; j<=n; ++j) { if(a[i][j] || a[j][i]) ans++; } if(ans == n-1) res++; } cout<< res <<endl; return 0; }