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 }

 

posted @ 2017-08-12 11:02  天之道,利而不害  阅读(139)  评论(0编辑  收藏  举报