简单的一道题,按照Ford算法求出闭包,然后再利用dfs打印结果即可,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
class Solve{
public:
int n, m;
vector<string> name;
int path[30][30];
int visit[30];
int find_name(string s){
for (int i = 0; i < name.size(); i++){
if (name[i] == s) return i;
}
name.push_back(s);
return name.size() - 1;
}
void Init(){
name.clear();
memset(path,0,sizeof(path));
memset(visit, 0, sizeof(visit));
for (int i = 0; i < n; i++) path[i][i] = 1;
for (int i = 0; i < m; i++){
string s1, s2;
cin >> s1 >> s2;
int id1 = find_name(s1);
int id2 = find_name(s2);
path[id1][id2] = 1;
}
for (int k = 0; k < n; k++){
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
path[i][j] = path[i][j] | (path[i][k] && path[k][j]);
}
}
}
}
void dfs(int i){
for (int t = 0; t < n; t++){
if (!visit[t]&&path[i][t]&&path[t][i]){
visit[t] = true;
cout << ", " << name[t];
dfs(t);
}
}
}
void Deal(){
for (int i = 0; i < n; i++){
if (!visit[i]){
visit[i] = 1;
cout << name[i];
dfs(i);
cout << endl;
}
}
}
};
int main(){
Solve a;
int flag = 0;
while (cin >> a.n >> a.m){
if (a.n == 0 && a.m == 0) break;
if (flag) cout << endl;
flag++;
a.Init();
cout << "Calling circles for data set " << flag << ":" << endl;
a.Deal();
}
return 0;
}