这个西班牙的UVa真的是给爷整吐了!
数据很小,暴力Flyod,
本题可Tarjan
记得当年吕老师强调 Flyod枚举循环的k一定是在最外层
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<string>
#include<algorithm>
#define Maxn 1005
using namespace std;
int d[Maxn][Maxn],vis[Maxn];
map<string,int> nam;
string name[Maxn];
int main(int argc,char* argv[]) {
//freopen("1.out","w",stdout);
int x,y,n,m,sum,kase = 0; string na1,na2;
while(scanf("%d %d",&n,&m ) == 2 && n) {
sum = 0;nam.clear();
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
for(int i=1; i<=m; i++) {
cin >> na1 >> na2;
if(nam.count(na1)) x = nam[na1];
else {
name[++sum] = na1;
nam[na1] = sum; x = sum;
}
if(nam.count(na2)) y = nam[na2];
else {
name[++sum] = na2;
nam[na2] = sum; y = sum;
}
d[x][y] = 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]));
printf("Calling circles for data set %d:\n",++kase);
for(int i=1; i<=n; i++){
if(vis[i]) continue;
cout << name[i];
for(int j=i+1; j<=n; j++) {
if(vis[j]) continue;
if(d[i][j] && d[j][i]){
vis[j] = 1;
cout << ", " << name[j];
}
}
printf("\n");
}
//printf("\n");
}
return 0;
}