Calling Circles UVA - 247
第一次接触传递闭包,有点懵。不过学习了一下map,强势记住了Floyd能算有向图的传递闭包,好像离散应该讲过。
1 #include<map> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 int n,m,cnt,kase; 9 bool vis[30]; 10 string Pe[30]; 11 int dp[30][30]; 12 map<string,int> ID; 13 14 void Inite(){ 15 cnt=0; 16 ID.clear(); 17 memset(dp,0,sizeof(dp)); 18 memset(vis,false,sizeof(vis)); 19 } 20 21 int get_ID(string name){ 22 if(ID.count(name)) return ID[name]; 23 ID[name]=++cnt; 24 Pe[cnt]=name; 25 return cnt; 26 } 27 28 void input(){ 29 string a,b; 30 for(int i=1;i<=m;i++){ 31 cin>>a>>b; 32 int x=get_ID(a),y=get_ID(b); 33 dp[x][y]=1; 34 } 35 } 36 37 void Floyd(){ 38 for(int k=1;k<=n;k++) 39 for(int i=1;i<=n;i++) 40 for(int j=1;j<=n;j++) 41 dp[i][j]=dp[i][j]||(dp[i][k]&&dp[k][j]); 42 } 43 44 void solve(){ 45 if(kase) cout<<endl; 46 printf("Calling circles for data set %d:\n",++kase); 47 Floyd(); 48 for(int i=1;i<=n;i++){ 49 if(vis[i]) continue; 50 cout<<Pe[i]; 51 for(int j=i+1;j<=n;j++){ 52 if(vis[j]) continue; 53 if(dp[i][j]&&dp[j][i]){ 54 vis[j]=true; 55 cout<<", "<<Pe[j]; 56 } 57 } 58 cout<<endl; 59 } 60 61 } 62 63 int main() 64 { kase=0; 65 while(~scanf("%d%d",&n,&m)){ 66 if(n==0&&m==0) break; 67 Inite(); 68 input(); 69 solve(); 70 } 71 return 0; 72 }