问题
分析
就是有向图的传递闭包,floyd算法判断u能否连到v,v能否连到u
注意,要在case中间加空行,最后一个case后面不能有空行
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <utility>
#include <map>
#include <string>
using namespace std;
const int maxn=30;
int vis[maxn];
vector<string> int2str;
map<string,int> str2int;
int n,m,g[maxn][maxn],kase=0;
string s1,s2;
inline int ID(string &s){
if(str2int.count(s)) return str2int[s];
int2str.push_back(s);
return str2int[s]=int2str.size()-1;
}
inline void print(int x){
for(int i=0;i<n;++i){
if(!vis[i] && (g[x][i]&&g[i][x])){ //成圈
vis[i]=1;
printf(", %s",int2str[i].c_str());
}
}
printf("\n");
}
int main(void){
while(scanf("%d%d",&n,&m)==2 && (n||m)){
str2int.clear();
int2str.clear();
memset(g,0,sizeof(g));
memset(vis,0,sizeof(vis));
for(int i=0;i<m;++i){
cin>>s1>>s2;
int t1=ID(s1),t2=ID(s2);
g[t1][t2]=1;
}
for(int k=0;k<n;++k){
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
g[i][j]=g[i][j]||(g[i][k]&&g[k][j]);
}
}
}
if(kase) printf("\n");
printf("Calling circles for data set %d:\n",++kase);
for(int i=0;i<n;++i){
if(!vis[i]){
vis[i]=1;
printf("%s",int2str[i].c_str());
print(i);
}
}
}
return 0;
}