求有向图的传递闭包,并输出各个连通分量的成员。
输出各个连通分量,可以递归输出。
代码:
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 40;
int n, m;
vector<string> vec;
bool data[maxn][maxn], vis[maxn];
int get_ID(string str) //判断名字是否存在,存在返回下标,不在则存入
{
int i;
for(i = 0; i < vec.size(); i++)
if(str == vec[i])
return i;
vec.push_back(str);
return vec.size() - 1;
}
void dfs(int x)
{
vis[x] = true;
for(int i = 0; i < n; i++)
{
if(data[x][i] && data[i][x])
if(!vis[i])
{
cout << ", " << vec[i];
dfs(i);
}
}
}
int main()
{
// freopen("1.txt", "r", stdin);
int t = 0, i, j, k;
string str1, str2;
while(cin >> n >> m)
{
memset(data, false, sizeof(data));
vec.clear();
if(n == 0 && m == 0)
break;
for(i = 0; i < n; i++)
data[i][i] = true;
for(i = 0; i < m; i++)
{
cin >> str1 >> str2;
data[get_ID(str1)][get_ID(str2)] = true;
}
for(k = 0; k < n; k++) //求传递闭包
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
data[i][j] = data[i][j] || (data[i][k] && data[k][j]);
memset(vis, false, sizeof(vis));
if(t > 0)
cout << endl;
cout << "Calling circles for data set " << ++t << ":" << endl;
for(i = 0; i < n; i++)
{
if(!vis[i])
{
cout << vec[i];
dfs(i);
cout << endl;
}
}
}
return 0;
}