強聯通分量的KOSARAJU算法

轉自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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章