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 }