首页 > 代码库 > UVa 247 电话圈(Floyd传递闭包)

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传递闭包)