強連通分量-tarjan演算法模板詳解

The_b-dn發表於2013-10-10

對於基本的演算法過程在這裡推薦一位大牛的分析:有向圖強連通分量的tarjan演算法

分析中結合圖形模擬演算法過程,我也是看了這位大牛的文章之後入門tarjan演算法,但是大牛的程式碼中沒有註釋,自己比較笨,看大牛的程式碼也用了很長時間理解,這裡給出大牛的程式碼模板結合自己的詳細解釋,希望以後自己來看一目瞭然,也希望能幫助剛接觸tarjan演算法的人更快理解

下面是大牛的程式碼(一些變數名有改動,希望更有助理解)

int top;//這個是用作棧頂的指標
int Stack[MAX];//維護的一個棧
bool instack[MAX];//instack[i]為真表示i在棧中 
int DFN[MAX],LOW[MAX];
int Belong[MAX];//Belong[i] = a; 表示i這個點屬於第a個連通分量
int Bcnt,Dindex;//Bcnt用來記錄連通分量的個數,Dindex表示到達某個點的時間
void tarjan(int u)
{
    int v;
    DFN[u]=LOW[u] = ++ Dindex;//這裡要注意 Dindex是初始化為0,這裡就不能 Dindex++; 不然第一個點的DFN和LOW就為0
    Stack[++ top] = u;
    instack[u] = true;
    for (edge *e = V[u] ; e ; e = e->next)//對所有可達邊的搜尋
    {
        v = e->t;
        if (!DFN[v])//這個if 就是用來更新LOW[u]
        {
            tarjan(v);
            if (LOW[v] < LOW[u])
                LOW[u] = LOW[v];
        }
        else if (instack[v] && DFN[v] < LOW[u])
            LOW[u] = DFN[v];
    }
    if (DFN[u] == LOW[u])//這裡表示找完一個強連通啦
    {
        Bcnt ++;//強連通個數加1
        do
        {
            v = Stack[top --];
            instack[v] = false;
            Belong[v] = Bcnt;
        }
        while (u != v);//一直到v=u都是屬於第Bcnt個強連通分量
    }
}
void solve()
{
    int i;
    top = Bcnt = Dindex = 0;
    memset(DFN,0,sizeof(DFN));
    for (i = 1; i <= N ; i ++)//這裡是一定要對所有點tarjan才能求出所有的點的強連通分量
        if (!DFN[i])
            tarjan(i);
}

如果對模板也比較熟悉就試著做 hdu1269迷宮城堡---就是判斷給出的圖是否為一個強連通,簡單的模板題

個人愚昧觀點,歡迎指正與討論




相關文章