【模板】 强连通分量分解

 1 #include<vector>
 2 #include<cstring>
 3 #define MAX_V 10050
 4 
 5 int V,E;                  //V表示顶点数,E表示边数(顶点标号为0~V-1)
 6 vector<int> G[MAX_V];     //图的邻接表表示
 7 vector<int> rG[MAX_V];    //把边反向后的图
 8 vector<int> vs;           //后序遍历顺序的顶点列表(即用一个栈模拟了回溯时的标号)
 9 bool used[MAX_V];         //DFS中用到的访问标记
10 int cmp[MAX_V];           //顶点所属强连通分量的拓扑序(0~k-1)
11 
12 //向图中添加一条从_from到_to的边
13 void add_edge(int _from,int _to)
14 {
15     G[_from].push_back(_to);
16     rG[_to].push_back(_from);
17 }
18 
19 //第一次在原图上的DFS
20 void dfs(int v)
21 {
22     used[v]=true;
23     for(int i=0;i<G[v].size();i++)
24         if(!used[G[v][i]])
25             dfs(G[v][i]);
26     vs.push_back(v);
27 }
28 
29 //第二次在反向图上的DFS
30 void rdfs(int v,int k)
31 {
32     used[v]=true;
33     cmp[v]=k;
34     for(int i=0;i<rG[v].size();i++)
35         if(!used[rG[v][i]])
36             rdfs(rG[v][i],k);
37 }
38 
39 //求解强连通分量(SCC:Strongly Connected Component),返回值为图中强连通分量的个数
40 int scc()
41 {
42     memset(used,false,sizeof(used));
43     vs.clear();
44     for(int v=0;v<V;v++)
45         if(!used[v])
46             dfs(v);
47 
48     memset(used,false,sizeof(used));
49     int k=0;
50     for(int i=vs.size()-1;i>=0;i--)
51         if(!used[vs[i]])
52         {
53             rdfs(vs[i],k);
54             k++;
55         }
56 
57     return k;
58 }

 

posted @ 2014-03-07 12:04  ~~Snail~~  阅读(229)  评论(0编辑  收藏  举报