题意:两人相互打电话(直接或间接),则在一个电话圈。即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;
}