【模板】 強連通份量分解

 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 }
相關文章
相關標籤/搜索