Uva247.Calling Circles (Floyd传递闭包)
Description
现有
n
个人
Solution
Floyd传递闭包
通关传递闭包运算,求出每个人之间的连通性。当且仅当 a→b 且 b→a 说明 a,b 在一个电话圈中。
Tarjan强连通分量
题面描述就是裸地Tarjan求强连通分量的题目,直接套板子就好。
Code
这里给出的是Floyd传递闭包的解法。
#include<bits/stdc++.h>
#define ll long long
#define nmax 50
using namespace std;
int mp[nmax][nmax];
bool isout[nmax];
string hashback[nmax];
map<string,int> mmp;
struct mes{
string a,b;
}mes[nmax * nmax];
int n,m,cnt = 1;
void floyd(){
for(int k = 1;k<=n;++k){
for(int i = 1;i<=n;++i){
for(int j = 1;j<=n;++j){
if(mp[i][k])
mp[i][j] = mp[i][j] || (mp[i][k] && mp[k][j]);
}
}
}
}
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int kase = 1;
while(cin>>n>>m){
if(n == 0 && m ==0) break;
if(kase>=2) cout<<endl;
cnt = 1;mmp.clear();
memset(mp,0,sizeof mp);
for(int i = 0;i<m;++i){
cin>>mes[i].a>>mes[i].b;
if(mmp.count(mes[i].a) == 0) {mmp[mes[i].a] = cnt,hashback[cnt] = mes[i].a;cnt++;}
if(mmp.count(mes[i].b) == 0) {mmp[mes[i].b] = cnt,hashback[cnt] = mes[i].b;cnt++;}
}
for(int i = 0;i<m;++i){
string a = mes[i].a,b = mes[i].b;
mp[mmp[a]][mmp[b]] = 1;
}
floyd();
memset(isout,0,sizeof isout);
cout<<"Calling circles for data set "<<kase++<<":"<<endl;
for(int i = 1;i<=n;++i){
if(isout[i]) continue;
cout<<hashback[i];isout[i] = true;
for(int j = 1;j<=n;++j){
if(i!=j&&mp[i][j] && mp[j][i]){
cout<<", "<<hashback[j];
isout[j] = true;
}
}
cout<<endl;
}
}
return 0;
}