傳遞閉包(例題POJ3660)

概念: 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; }
相關文章
相關標籤/搜索