floyd騷操做——傳遞閉包

傳遞閉包的含義指經過傳遞性推導出儘可能多的元素之間的關係,而傳遞閉包通常都是採用floyd算法。ios

下面用兩道題來實現傳遞閉包:算法

Problem 1(POJ3660):閉包

題目連接:http://poj.org/problem?id=3660ide

題目:url

題意:n頭牛參加比賽,給你m對關係(譬如給你a和b,那麼給的就是a必贏b,固然,b能贏c,那麼a也能贏c),問能肯定多少頭牛的排名。spa

思路:首先咱們用flod算法將全部的關係進行傳遞,只要u能勝v,那麼咱們就將d[u][v]設爲1,最後若是二者之間有d[u][v]=1或d[v][u]且兩者不能同時出現時ans++。.net

代碼實現以下:debug

 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)code

題目連接:http://poj.org/problem?id=1094blog

題目:

題意:給你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
相關文章
相關標籤/搜索