原题链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=4&page=show_problem&problem=183
题目大意:
输出每个电话圈中的人。
电话圈中的任意一个人可以直接或者间接给圈内的任意其他人打电话。
注意输出:' , '后有空格,每两组测试数据空一行。
详见代码:
#include<iostream>
#include<cstring>
#include<string>
#include<map>
#include<vector>
using namespace std;
const int N = 25 + 1;
int G[N][N];
bool vis[N];//记录是否访问过
int k,n,m;
vector<string>name;//对应次序的名字
map<string, int>peo;//名字与次序的关系
void init()
{
memset(G, 0, sizeof(G));
memset(vis, 0, sizeof(vis));
name.clear();
peo.clear();
k = 0;
}
void DFS(int u)
{
vis[u] = true;
for (int v = 0; v < n; v++)
{
if (G[u][v]&&G[u][v]==G[v][u]&&!vis[v]) //两人之间可以相互联系,并且没有访问过
{
cout << ", " << name[v];
DFS(v);
}
}
}
int main()
{
int kase=1;
while (cin >> n >> m&&(n||m))// n==0&&m==0 终止循环
{
init();
string u, v;
for (int i = 0; i < m; i++)
{
cin >> u >> v;
if (!peo.count(u)) {
peo[u] = k++;
name.push_back(u);
}
if (!peo.count(v)) {
peo[v] = k++;
name.push_back(v);
}
G[peo[u]][peo[v]] = 1;
}
for (int h = 0; h < n; h++) //floyd传递闭包处理,使间接联系的可以直接联系
{
for (int i = 0; i < n; i++)
{
if (G[i][h])
{
for (int j = 0; j < n;j++)
if (G[h][j]) G[i][j] = 1;
}
}
}
if (kase>1)cout << endl;
cout << "Calling circles for data set " << kase++ << ":" << endl;
for (int i = 0; i < n; i++)
{
if (!vis[i])
{
cout << name[i];
DFS(i);
cout << endl;
}
}
}
return 0;
}