1.题目描述:点击打开链接
2.解题思路:本题要求寻找电话圈:圈内的人两两均直接或间接地通过电话。这正是Floyd算法的用武之地。先用Floyd算法求出传递闭包。然后扫描所有人,将处在一个圈里的人标记并放入数组,随后输出即可。
3.代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;
#define N 25+5
int g[N][N];
int vis[N];
int n,m;
vector<string>names;
map<string,int>IDcache;
vector<string>circle;
int id(string s)
{
if(IDcache.count(s))
return IDcache[s];
names.push_back(s);
return IDcache[s]=names.size()-1;
}
int main()
{
freopen("t.txt","r",stdin);
int rnd=0;
while(cin>>n>>m&&(n||m))
{
memset(g,0,sizeof(g));
memset(vis,0,sizeof(vis));
IDcache.clear();
names.clear();
string s,t;
for(int i=0;i<m;i++)
{
cin>>s>>t;
int u=id(s),v=id(t);
g[u][v]=1;
}
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
g[i][j]|=g[i][k]&&g[k][j];//求传递闭包
if(rnd)cout<<endl;
printf("Calling circles for data set %d:\n",++rnd);
int len=names.size();
for(int i=0;i<len;i++)
{
circle.clear();
if(!vis[i])circle.push_back(names[i]);
vis[i]=1;
for(int j=i;j<len;j++)
if(g[i][j]&&g[j][i]&&!vis[j])
{
vis[j]=1;
circle.push_back(names[j]);
}
int len=circle.size();
for(int i=0;i<len;i++)
{
cout<<circle[i];
if(i<len-1)cout<<", ";
if(i==len-1)cout<<endl;
}
}
}
return 0;
}