UVA 247 电话圈 (floyd传递闭包 + dfs输出连通分量的点)

时间:2023-12-05 09:50:26

题意:输出所有的环;

思路:数据比较小,用三层循环的floyd传递闭包(即两条路通为1,不通为0,如果在一个环中,环中的所有点能互相连通),输出路径用dfs,递归还没有出现过的点(vis),输出并递归该点与其他点能互达的点;

 #include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
#define repu(i,a,b) for(int i=a;i<b;i++)
#define INF 10010
vector<string> str;
#define N 30
int d[N][N],vis[N]; int ID(string s)
{
repu(i,,str.size())
if(str[i] == s)
return i;
str.push_back(s);
return str.size()-;
} int n,m;
int dfs(int k)
{
vis[k] = ;
repu(j,,n)
if(!vis[j] && d[j][k] && d[k][j])
{
cout<<", "<<str[j];
dfs(j);
}
} int main()
{
int kase = ;
while(scanf("%d%d",&n,&m) && n && m)
{
str.clear();
string s,c;
if(kase)
printf("\n");
repu(i,,n)
repu(j,,n)
d[i][j] = (i == j)?:; repu(i,,m)
{
cin>>s>>c;
int x = ID(s);
int y = ID(c);
d[x][y] = ;
}
printf("Calling circles for data set %d:\n",++kase);
repu(k,,n)///传递闭包
repu(i,,n)
repu(j,,n)
d[i][j] |= (d[i][k] && d[k][j]); memset(vis,,sizeof(vis));///递归输出路径
repu(i,,n)
if(!vis[i])
{
cout<<str[i];
dfs(i);
printf("\n");
}
}
return ;
}