UVa 247 电话圈(Floyd传递闭包)

Posted 谦谦君子,陌上其华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 247 电话圈(Floyd传递闭包)相关的知识,希望对你有一定的参考价值。

https://vjudge.net/problem/UVA-247

题意:

如果两个人相互打电话,则说他们在同一个电话圈里。例如,a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里;如果e打给f但f不打给e,则不能推出e和f在同一个电话圈里,输出所有电话圈。

 

思路:

通过Floyd求一个传递闭包。最后dfs输出每一个电话圈即可。

传递闭包的求法:

1 for (int k = 0; k < n;k++)
2 for (int i = 0; i < n;i++)
3 for (int j = 0; j < n; j++)
4     d[i][j] = d[i][j] || (d[i][k] && d[k][j]);

 

 1 #include<iostream> 
 2 #include<cstring>
 3 #include<string>
 4 #include<algorithm>
 5 #include<map>
 6 #include<vector>
 7 using namespace std;
 8 
 9 int n, m;
10 int d[30][30];
11 string s1, s2;
12 map<string, int> ID;
13 vector<string> name;
14 int vis[30];
15 
16 void dfs(int k)
17 {
18     vis[k] = 1;
19     for (int i = 0; i < n; i++)
20     {
21         if (d[k][i] && d[i][k])
22         {
23             if (!vis[i])
24             {
25                 cout << ", " << name[i];
26                 dfs(i);
27             }
28         }
29     }
30 }
31 
32 int main()
33 {
34     //freopen("D:\\txt.txt", "r", stdin);
35     int kase = 1;
36     while (scanf("%d%d", &n, &m))
37     {
38         if (n == 0 && m == 0)    break;
39         if (kase > 1)     printf("\n");
40         memset(d, 0, sizeof(d));
41         memset(vis, 0, sizeof(vis));
42         ID.clear();
43         name.clear();
44         int cnt = 0;
45         for (int i = 0; i < m; i++)
46         {
47             cin >> s1 >> s2;
48             if (!ID.count(s1))
49             {
50                 ID[s1] = cnt++;
51                 name.push_back(s1);
52             }
53             if (!ID.count(s2))
54             {
55                 ID[s2] = cnt++;
56                 name.push_back(s2);
57             }
58             int x = ID[s1];
59             int y = ID[s2];
60             d[x][y] = 1;
61         }
62 
63         for (int k = 0; k < n;k++)
64         for (int i = 0; i < n;i++)
65         for (int j = 0; j < n; j++)
66             d[i][j] = d[i][j] || (d[i][k] && d[k][j]);
67 
68         printf("Calling circles for data set %d:\n", kase++);
69         for (int i = 0; i < n; i++)
70         {
71             if (!vis[i])
72             {
73                 cout << name[i];
74                 dfs(i);
75                 printf("\n");
76             }
77         }
78     }
79     return 0;
80 }

 

以上是关于UVa 247 电话圈(Floyd传递闭包)的主要内容,如果未能解决你的问题,请参考以下文章

UVa247 Calling Circles (Floyd,DFS)

电话圈(floyd)

World Finals 1996 Uva (Floyd求闭包)

uva247(floyd+dfs)

UVa 11549 计算器谜题(Floyd判圈算法)

UVA11549 计算机谜题(Floyd判圈算法)