首页 > 代码库 > 电话圈(floyd)

电话圈(floyd)

题意:

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

//floyd求传递闭包,dfs求出电话圈;

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<vector>
 6 #include<map>
 7 using namespace std;
 8 string s1,s2;//姓名 
 9 int n,m;
10 vector<string>name;//动态数组名字 
11 map<string,int>ID;//把人给编号 
12 int vis[30];//是否访问 
13 int d[30][30];//是否能通电话 
14 void dfs(int k)//深搜求电话圈 
15 {
16     vis[k]=1;
17     for(int i=0;i<n;i++)
18     {
19         if(!vis[i]&&d[i][k]&&d[k][i])
20         {
21             cout<<name[i]<<" ";
22             dfs(i);
23         }
24     }
25 }
26 int main()
27 {
28     while(scanf("%d%d",&n,&m)!=EOF)//n个人m个电话圈 
29     {
30         memset(vis,0,sizeof(vis));
31         memset(d,0,sizeof(d));
32         int cnt=0;
33         name.clear();
34         ID.clear();
35         for(int i=1;i<=m;i++)
36         {
37             cin>>s1>>s2;
38             if(!ID.count(s1))//这个人没有 
39             {
40                 ID[s1]=cnt++;//给这个人编号 
41                 name.push_back(s1);//进入队列 
42             }
43             if(!ID.count(s2))
44             {
45                 ID[s2]=cnt++;
46                 name.push_back(s2);
47             }
48             int x=ID[s1];
49             int y=ID[s2];
50             d[x][y]=1;//这两个人可以互相通电话 
51         }
52         for(int k=0;k<n;k++)//floyd 
53         for(int i=0;i<n;i++)
54         for(int j=0;j<n;j++)
55         d[i][j]=d[i][j]||d[i][k]&&d[k][j];
56         for(int i=0;i<n;i++)//求电话圈 
57         {
58             if(!vis[i])
59             {
60                 cout<<name[i]<<" ";
61                 dfs(i);
62                 printf("\n");//在这里有个回车。。不然没形成一个电话圈时,它会输出一个电话圈 
63             }
64          }
65     }
66 }
View Code

//学到的floyd判圈,dfs求圈

电话圈(floyd)