題意:
如果兩個人相互打電話,則說他們在同一個電話圈里。例如,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求圈