题意:两人相互打电话(直接或间接),则在一个电话圈。即a给b打电话,b给c打电话,则a给c间接打电话。
注意:1、注意标记。2、注意输出格式。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<sstream> #include<cctype> #include<cmath> #include<cstdlib> #include<algorithm> #include<stack> #include<queue> #include<deque> #include<set> #include<map> #include<list> using namespace std; const int MAXN=10000+10; const int INF=0x7f7f7f7f; const double PI=acos(1.0); typedef long long ll; typedef unsigned long long llu; map<string,int> ma; char s1[30],s2[30]; string s[30]; int d[30][30]; int vis[30]; int n; int dfs(int w)//遍历,若在一个电话圈里,则输出,注意标记 { vis[w]=1; for(int i=1; i<=n; i++) { if(!vis[i]&&d[w][i]&&d[i][w]) { printf(", %s",s[i].c_str());//注意格式--空格 vis[i]=1; } } } int main() { int m; int cnt=0; while(scanf("%d%d",&n,&m)==2&&n&&m) { memset(d,0,sizeof(d)); memset(vis,0,sizeof(vis)); ma.clear();//!!! int cas=0; while(m--) { scanf("%s%s",s1,s2); if(!ma.count(s1))//按输入顺序,依次给名字标号,并存进s { ma[s1]=++cas; s[cas]=string(s1); } if(!ma.count(s2)) { ma[s2]=++cas; s[cas]=string(s2); } int i=ma[s1],j=ma[s2]; d[i][j]=1; } for(int k=1; k<=n; k++)//有向图的传递闭包 { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { d[i][j]=d[i][j]||(d[i][k]&&d[k][j]); } } } if(cnt) printf("\n"); printf("Calling circles for data set %d:\n",++cnt); for(int i=1; i<=n; i++) { if(vis[i]) continue; if(!vis[i]) printf("%s",s[i].c_str()); dfs(i); printf("\n"); } } return 0; }