传递闭包的含义指通过传递性推导出尽量多的元素之间的关系,而传递闭包一般都是采用floyd算法。
下面用两道题来实现传递闭包:
Problem 1(POJ3660):
题目链接:http://poj.org/problem?id=3660
题目:
题意:n头牛参加比赛,给你m对关系(譬如给你a和b,那么给的就是a必赢b,当然,b能赢c,那么a也能赢c),问能确定多少头牛的排名。
思路:首先我们用flod算法将所有的关系进行传递,只要u能胜v,那么我们就将d[u][v]设为1,最后如果两者之间有d[u][v]=1或d[v][u]且二者不能同时出现时ans++。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef pair<ll, ll> pll; 18 typedef pair<int, ll> pil;; 19 typedef pair<int, int> pii; 20 typedef unsigned long long ull; 21 22 #define lson i<<1 23 #define rson i<<1|1 24 #define bug printf("*********\n"); 25 #define FIN freopen("D://code//in.txt", "r", stdin); 26 #define debug(x) cout<<"["<<x<<"]" <<endl; 27 #define IO ios::sync_with_stdio(false),cin.tie(0); 28 29 const double eps = 1e-8; 30 const int mod = 10007; 31 const int maxn = 4500 + 7; 32 const double pi = acos(-1); 33 const int inf = 0x3f3f3f3f; 34 const ll INF = 0x3f3f3f3f3f3f3f; 35 36 int n, m, u, v; 37 int relationship[107][107]; 38 39 int main() { 40 //FIN; 41 scanf("%d%d", &n, &m); 42 memset(relationship, 0, sizeof(relationship)); 43 for(int i = 1; i <= m; i++) { 44 scanf("%d%d", &u, &v); 45 relationship[u][v] = 1; 46 } 47 for(int k = 1; k <= n; k++) { 48 for(int i = 1; i <= n; i++) { 49 for(int j = 1; j <= n; j++) { 50 if(relationship[i][k] && relationship[k][j]) { 51 relationship[i][j] = 1; 52 } 53 } 54 } 55 } 56 int ans = 0, j; 57 for(int i = 1; i <= n; i++) { 58 for(j = 1; j <= n; j++) { 59 if(i == j) continue; 60 if(relationship[i][j] == 0 && relationship[j][i] == 0) { 61 break; 62 } 63 } 64 if(j > n) ans++; 65 } 66 printf("%d\n", ans); 67 return 0; 68 }