UVA - 247 - Calling Circles(floyd算法)

题意:输出所有电话圈(电话圈:要求两个人直接或间接互相接通)

用floyd算法求出传递闭包,即把所有间接接通的两个人都找出来并且标记

然后再用并查集维护

 

 1 #include<cstdio>  
 2 #include<cstring>  
 3 #include<cctype>  
 4 #include<cstdlib>  
 5 #include<cmath>  
 6 #include<iostream>  
 7 #include<sstream>  
 8 #include<iterator>  
 9 #include<algorithm>  
10 #include<string>  
11 #include<vector>  
12 #include<set>  
13 #include<map>  
14 #include<deque>  
15 #include<queue>  
16 #include<stack>  
17 #include<list>  
18 typedef long long ll;  
19 typedef unsigned long long llu;  
20 const int MAXN = 100 + 10;  
21 const int MAXT = 10000 + 10;  
22 const int INF = 0x3f3f3f3f;  
23 const double pi = acos(-1.0);  
24 const double EPS = 1e-6;  
25 using namespace std;  
26   
27 int n, lur, m, g[MAXN][MAXN], fa[MAXN];  
28   
29 void floyd(){  
30     for(int k = 1; k <= n; ++k)  
31         for(int i = 1; i <= n; ++i)  
32             for(int j = 1; j <= n; ++j)  
33                 g[i][j] = min(g[i][j], g[i][k] + g[k][j]);  
34 }  
35   
36 int find(int v){  
37     return fa[v] = fa[v] == v ? v : find(fa[v]);  
38 }  
39   
40 void merge(int x, int y){  
41     int a = find(x), b = find(y);  
42     if(a < b)  fa[b] = a;  
43     else  fa[a] = b;  
44 }  
45   
46 map<string, int> id;  
47 map<int, string> id2;  
48   
49 int getid(string &s){  
50     if(id.count(s))  return id[s];  
51     id[s] = ++lur;  
52     id2[lur] = s;  
53     return lur;  
54 }  
55   
56 int main(){  
57     int ca = 0;  
58     while(scanf("%d%d", &n, &m) == 2 && (n || m)){  
59         memset(g, INF, sizeof g);  
60         id.clear();  
61         id2.clear();  
62         for(int i = 0; i <= n + 1; ++i)  fa[i] = i;  
63         lur = 0;  
64         string tmp1, tmp2;  
65         int id1, id3;  
66         for(int i = 0; i < m; ++i){  
67             cin >> tmp1 >> tmp2;  
68             id1 = getid(tmp1);  
69             id3 = getid(tmp2);  
70             g[id1][id3] = 1;  
71         }  
72         floyd();  
73         if(ca)  printf("\n");  
74         printf("Calling circles for data set %d:\n", ++ca);  
75         for(int i = 1; i <= n; ++i)  
76             for(int j = i + 1; j <= n; ++j)  
77                 if(g[i][j] != INF && g[j][i] != INF)  merge(i, j);  
78         set<int> f;  
79         for(int i = 1; i <= n; ++i){  
80             f.insert(find(i));  
81         }  
82         for(set<int>::iterator i = f.begin(); i != f.end(); ++i){  
83             int father = *i;  
84             bool flag = false;  
85             for(int j = 1; j <= n; ++j){  
86                 if(find(j) != father)  continue;  
87                 if(flag)  printf(", ");  
88                 flag = true;  
89                 cout << id2[j];  
90             }  
91             cout << endl;  
92         }  
93     }  
94     return 0;  
95 }  

 

posted @ 2016-10-25 10:41  TianTengtt  阅读(147)  评论(0)    收藏  举报