UVA 247 电话圈 (floyd传递闭包 + dfs输出连通分量的点)

题意:输出所有的环;

思路:数据比较小,用三层循环的floyd传递闭包(即两条路通为1,不通为0,如果在一个环中,环中的所有点能互相连通),输出路径用dfs,递归还没有出现过的点(vis),输出并递归该点与其他点能互达的点;

 1 #include <cstdio>
 2 #include <vector>
 3 #include <string>
 4 #include <cstring>
 5 #include <iostream>
 6 using namespace std;
 7 #define repu(i,a,b) for(int i=a;i<b;i++)
 8 #define INF 10010
 9 vector<string> str;
10 #define N 30
11 int d[N][N],vis[N];
12 
13 int ID(string s)
14 {
15     repu(i,0,str.size())
16     if(str[i] == s)
17         return i;
18     str.push_back(s);
19     return str.size()-1;
20 }
21 
22 int n,m;
23 int dfs(int k)
24 {
25     vis[k] = 1;
26     repu(j,0,n)
27     if(!vis[j] && d[j][k] && d[k][j])
28     {
29         cout<<", "<<str[j];
30         dfs(j);
31     }
32 }
33 
34 int main()
35 {
36     int kase = 0;
37     while(scanf("%d%d",&n,&m) && n && m)
38     {
39         str.clear();
40         string s,c;
41         if(kase)
42             printf("\n");
43         repu(i,0,n)
44         repu(j,0,n)
45         d[i][j] = (i == j)?1:0;
46 
47         repu(i,0,m)
48         {
49             cin>>s>>c;
50             int x = ID(s);
51             int y = ID(c);
52             d[x][y] = 1;
53         }
54         printf("Calling circles for data set %d:\n",++kase);
55         repu(k,0,n)///传递闭包
56         repu(i,0,n)
57         repu(j,0,n)
58         d[i][j] |= (d[i][k] && d[k][j]);
59 
60         memset(vis,0,sizeof(vis));///递归输出路径
61         repu(i,0,n)
62         if(!vis[i])
63         {
64             cout<<str[i];
65             dfs(i);
66             printf("\n");
67         }        
68     }
69     return 0;
70 }
View Code

 

posted @ 2015-05-16 22:58  一麻袋码的玛侬  阅读(161)  评论(0编辑  收藏  举报