题目大意 如果两个人互相打电话(直接或间接),则说明他们在同一个电话圈里。但如果a打给b,b不打给a 就不算。(刘汝佳书上的描述简化)
因为题目数据范围很小 所以可以给所有打过电话的人直接建一条边,然后跑floyd,如果d[i][j]和d[j][i]都不是inf i和j就是一个圈子里的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#define scnaf scanf
#define cahr char
#define bug puts("bugbugbug");
using namespace std;
typedef long long ll;
const int inf=1000000000;
string print[100];
int d[100][100];
int f[100];
int n;
void init()
{
for(int i=0; i<=30; i++)
for(int j=0; j<=30; j++)
{
if(i==j)d[i][j]=0;
else d[i][j]=inf;
}
}
void Floyd()
{
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(d[i][k]<inf&&d[k][j]<inf)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
int Case=0;
void Print()
{
int vis[30] = {0};
if(Case) puts("");
printf("Calling circles for data set %d:\n",++Case);
for(int i = 1; i <= n; ++i) if(!vis[i])
{
cout<<print[i];
vis[i] = 1;
for(int j = 1; j <= n; ++j) if(!vis[j] && d[i][j]!=inf && d[j][i]!=inf)
{
printf(", ");
cout<<print[j];//%s",name[j]);
vis[j] = 1;
}
puts("");
}
}
map<string,int>mp;
int main()
{
int m;
while(~scnaf("%d%d",&n,&m)&&n+m)
{
mp.clear();
init();
string a,b;
int cnt=1;
for(int i=0; i<m; i++)
{
int aa,bb;
cin>>a>>b;
if(mp[a]==0)
{
mp[a]=cnt;
print[cnt++]=a;
}
aa=mp[a];
if(mp[b]==0)
{
mp[b]=cnt;
print[cnt++]=b;
}
bb=mp[b];
d[aa][bb]=1;
}
Floyd();
Print();
}
}