1. 程式人生 > >floyd騷操作——傳遞閉包

floyd騷操作——傳遞閉包

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++。

代碼實現如下:

技術分享圖片
 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 }
View Code

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騷操作——傳遞閉包