题目:
思路:
利用Floyd求传递闭包(mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);),当mp[i][j]=1&&mp[j][i]=1的时候,i 和 j就是在同一个电话圈中。
代码:
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define MAX 1000000000 #define FRE() freopen("in.txt","r",stdin) #define FRO() freopen("out.txt","w",stdout) using namespace std; typedef long long ll; typedef pair<int,ll> pii; const int maxn = 30; int n,m,cnt; map<string,int> idx; string name1,name2; string st[maxn]; int mp[maxn][maxn],vis[maxn]; int id(string name){ if(!idx.count(name)){ idx[name] = cnt; st[cnt] = name; return cnt++; } return idx[name]; } int main(){ //FRE(); int kase = 0; while(scanf("%d%d",&n,&m) && n){ memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); idx.clear(); cnt=0; for(int i=0; i<m; i++){ cin>>name1>>name2; int p = id(name1),q = id(name2); mp[p][q] = 1; } for(int k=0; k<n; k++){ for(int i=0; i<n; i++){ for(int j=0; j<n; j++){ mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]); } } } if(kase)cout<<endl; cout<<"Calling circles for data set "<<++kase<<":"<<endl; for(int i=0; i<n; i++){ if(vis[i]==0){ cout<<st[i]; vis[i] = 1; for(int j=i+1; j<n; j++){ if(vis[j]==0&&mp[i][j]&&mp[j][i]){ cout<<", "<<st[j]; vis[j]=1; } } cout<<endl; } } } return 0; }