轉自NOCOW
參考:http://m.blog.csdn.net/article/details?id=45692005
#include <iostream>
using namespace std;
const int MAXV = 1024;
int g[MAXV][MAXV], dfn[MAXV], num[MAXV], n, m, scc, cnt;
void dfs(int k)
{
num[k] = 1;
for(int i=1; i<=n; i++)
if(g[k][i] && !num[i])
dfs(i);
dfn[++cnt] = k; //記錄第cnt個出棧的頂點爲k
}
void ndfs(int k)
{
num[k] = scc; //本次DFS染色的點,都屬於同一個scc,用num數組做記錄
for(int i=1; i<=n; i++)
if(g[i][k] && !num[i]) //注意我們訪問的原矩陣的對稱矩陣
ndfs(i);
}
void kosaraju()
{
int i, j;
for(i=1; i<=n; i++) //DFS求得拓撲排序
if(!num[i])
dfs(i);
memset(num, 0, sizeof num);
/* 我們本需對原圖的邊反向,但由於我們使用鄰接矩陣儲存圖,所以反向的圖的鄰接矩陣
即原圖鄰接矩陣的對角線對稱矩陣,所以我們什麼都不用做,只需訪問對稱矩陣即可*/
for(i=n; i>=1; i--)
if(!num[dfn[i]]){ //按照拓撲序進行第二次DFS
scc++;
ndfs(dfn[i]);
}
cout<<"Found: "<<scc<<endl;
}
int main()
{
int i, j;
cin>>n>>m;
for(i=1; i<=m; i++){
int x, y, z;
cin>>x>>y>>z;
g[x][y] = z;
}
kosaraju();
return 0;
}