思路:利用的Floyd判圈,如果i能到j,j也能到i说明i和j在同一个圈里。每个人的名字可用map编号。最后DFS打印答案即可。
AC代码
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 25 + 5;
int d[maxn][maxn];
int cur, n, m;
map<string, int>Hash;
string name[maxn];
int get_ID(string &p) {
if(!Hash.count(p)) {
name[cur] = p;
Hash[p] = cur++;
}
return Hash[p];
}
bool vis[maxn];
void dfs(int u){ //dfs求联通分量
vis[u] = true;
for(int i = 0; i < n; ++i) {
if(vis[i] || !d[u][i] || !d[i][u]) continue;
cout << ", " << name[i];
vis[i] = true;
dfs(i);
}
}
int main() {
int kase = 0;
while(scanf("%d%d", &n, &m) == 2 && n && m) {
Hash.clear();
if(kase++) printf("\n");
cur = 0;
memset(d, 0, sizeof(d));
string x, y;
for(int i = 0; i < m; ++i) {
cin >> x >> y;
int a = get_ID(x), b = get_ID(y);
d[a][b] = 1;
}
//floyd
for(int k = 0; k < n; ++k)
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
d[i][j] = d[i][j] || (d[i][k] && d[k][j]);
memset(vis, false, sizeof(vis));
printf("Calling circles for data set %d:\n", kase);
for(int i = 0; i < n; ++i) {
if(vis[i]) continue;
cout << name[i];
dfs(i);
printf("\n");
}
}
return 0;
}
如有不当之处欢迎指出!