floyd騷操作——傳遞閉包
阿新 • • 發佈:2018-07-30
name its for %s ebe 所有 分享圖片 main cstring
傳遞閉包的含義指通過傳遞性推導出盡量多的元素之間的關系,而傳遞閉包一般都是采用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++。
代碼實現如下:
1View Code#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 #definerson 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 }
Problem 2(POJ1094)
題目鏈接:http://poj.org/problem?id=1094
題目:
題意:給你n個大寫字母,m對大小關系,根據他給的關系推測是否有大小矛盾的情況。如果有矛盾的就輸出是在第幾組關系時矛盾;如果不矛盾,判斷只需要前t對組關系就能推測出他們從小到大的排序;如果沒有以上兩種情況就輸入無法確定。
思路:對於每輸入一對關系就跑一次floyd判斷一遍,如果能推測出他們的關系,那麽就跑一邊拓撲排序求出他們從小打到的排序情況;如果有矛盾的關系就直接輸出是在第幾組關系時矛盾;如果沒有以上情況就輸出無法確定。
代碼實現如下:
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, t, flag; 37 char s[1007][5]; 38 int d[30][30], in[30], num[30]; 39 vector<int> G[30]; 40 41 bool floyd() { 42 for(int k = 1; k <= n; k++) { 43 for(int i = 1; i <= n; i++) { 44 for(int j = 1; j <= n; j++) { 45 if(d[i][k] && d[k][j]) { 46 d[i][j] = 1; 47 } 48 } 49 } 50 } 51 for(int i = 1; i <= n; i++) { 52 for(int j = 1; j <= n; j++) { 53 if(i == j) continue; 54 if((d[i][j] && d[j][i]) || (d[i][j] == 0 && d[j][i] == 0)) { 55 return false; 56 } 57 } 58 } 59 return true; 60 } 61 62 void topsort(int m) { 63 t = 0; 64 for(int i = 1; i <= n; i++) { 65 G[i].clear(); 66 } 67 memset(in, 0, sizeof(in)); 68 for(int i = 1; i <= m; i++) { 69 int x = s[i][0] - ‘A‘ + 1, y = s[i][2] - ‘A‘ + 1; 70 G[x].push_back(y); 71 in[y]++; 72 } 73 queue<int> q; 74 for(int i = 1; i <= n; i++) { 75 if(in[i] == 0) { 76 q.push(i); 77 } 78 } 79 while(!q.empty()) { 80 int x = q.front(); q.pop(); 81 num[t++] = x; 82 for(int i = 0; i < G[x].size(); i++) { 83 int v = G[x][i]; 84 in[v]--; 85 if(in[v] == 0) { 86 q.push(v); 87 } 88 } 89 } 90 } 91 92 int main() { 93 //FIN; 94 while(~scanf("%d%d", &n, &m)) { 95 if(n == 0 && m == 0) break; 96 memset(d, 0, sizeof(d)); 97 for(int i = 1; i <= m; i++) { 98 scanf("%s", s[i]); 99 } 100 flag = 0; 101 for(int i = 1; i <= m; i++) { 102 int x = s[i][0] - ‘A‘ + 1, y = s[i][2] - ‘A‘ + 1; 103 d[x][y] = 1; 104 if(floyd()) { 105 printf("Sorted sequence determined after %d relations: ", i); 106 topsort(i); 107 for(int i = 0; i < t; i++) { 108 printf("%c", num[i] - 1 + ‘A‘); 109 } 110 printf(".\n"); 111 flag = 1; 112 } else { 113 for(int j = 1; j <= n; j++) { 114 for(int k = 1; k <= n; k++) { 115 if(j == k) continue; 116 if((d[j][k] && d[k][j])) { 117 printf("Inconsistency found after %d relations.\n", i); 118 flag = 1; 119 break; 120 } 121 } 122 if(flag) break; 123 } 124 } 125 if(flag) break; 126 } 127 if(!flag) printf("Sorted sequence cannot be determined.\n"); 128 } 129 return 0; 130 }View Code
floyd騷操作——傳遞閉包