第一个强连通分量的题。

  题意:有一堆人,a给b打电话表示a有一条向b的边,一个强连通分量代表一个电话圈,把每个电话圈里的人在一行内输出出来。

  直接上模板即可,但是要注意把string用map映射一下的技巧。

  代码如下:

 

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <string>
 5 #include <iostream>
 6 #include <vector>
 7 #include <map>
 8 #include <stack>
 9 using namespace std;
10 
11 int n,m;
12 vector<string> names;
13 vector<int> G[30];
14 map<string,int> mp;
15 stack<int> S;
16 int tot;
17 int belong[30],scc_cnt,low[30],dfn[30],dfs_clock;
18 
19 void dfs(int u)
20 {
21     dfn[u]=low[u]=++dfs_clock;
22     S.push(u);
23     for(int i=0;i<G[u].size();i++)
24     {
25         int v = G[u][i];
26         if(!dfn[v])
27         {
28             dfs(v);
29             low[u]=min(low[u],low[v]);
30         }
31         else if(!belong[v])
32         {
33             low[u]=min(low[u],low[v]);
34         }
35     }
36     if(dfn[u]==low[u])
37     {
38         scc_cnt++;
39         for(;;)
40         {
41             int x = S.top();S.pop();
42             belong[x] = scc_cnt;
43             if(x==u) break;
44         }
45     }
46 }
47 
48 void scc()
49 {
50     dfs_clock=scc_cnt=0;
51     memset(belong,0,sizeof(belong));
52     memset(dfn,0,sizeof(dfn));
53     for(int i=0;i<n;i++) if(!dfn[i]) dfs(i);
54 }
55 
56 void print()
57 {
58     vector<int> ans[30];
59     for(int i=0;i<n;i++) ans[belong[i]].push_back(i);
60     for(int i=1;i<=scc_cnt;i++)
61     {
62         for(int j=0;j<ans[i].size();j++)
63         {
64             if(j) printf(", ");
65             cout<<names[ans[i][j]];
66         }
67         puts("");
68     }
69 }
70 
71 int main()
72 {
73     int cnt=1;
74     while(scanf("%d%d",&n,&m)==2)
75     {
76         tot=0;
77         names.clear();
78         mp.clear();
79         for(int i=0;i<n;i++) G[i].clear();
80         if(n==0 && m==0) break;
81         for(int i = 1; i <= m;i++)
82         {
83             string u,v;
84             cin>>u>>v;
85             if(mp.find(u)==mp.end()) mp[u]=tot++,names.push_back(u);
86             if(mp.find(v)==mp.end()) mp[v]=tot++,names.push_back(v);
87             G[mp[u]].push_back(mp[v]);
88         }
89         scc();
90 
91         if(cnt != 1) cout << endl;
92         cout << "Calling circles for data set " << cnt ++ <<":" << endl;
93         //printf("Calling circles for data set %d:\n",cnt++);
94         print();
95         //puts("");
96     }
97     return 0;
98 }

 

  但是搞不懂的是为什么注释掉的输出部分是错的呢- -