题意:
如果两个人相互打电话,则说他们在同一个电话圈里。例如,a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里;如果e打给f但f不打给e,则不能推出e和f在同一个电话圈里,输出所有电话圈。
//floyd求传递闭包,dfs求出电话圈;
//还有循环一定从0开始啊,标记人也要 第0个,第1个,第2个。。。。。因为动态数组你一压进去就是从0开始
//所以你之前做才一直错啊 从0开始
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 }
//学到的floyd判圈,dfs求圈