有向圖的強連通份量的求解算法Tarjan

Tarjan算法

Tarjan算法是基於dfs算法,每個強連通份量爲搜索樹中的一顆子樹。搜索時,把當前搜索樹中的未處理的結點加入一個棧中,回溯時能夠判斷棧頂到棧中的結點是否是在同一個強連通份量中。當dfn[u]=low[u]時,以u爲根的搜索子樹上的全部結點是一個強連通份量,其中dfn[]值表示結點的深度優先數,low[]值表示結點能夠到達的優先數最小的祖先。算法

Tarjan僞代碼以下:markdown

Tarjan(u)
{
    dfn[u] = low[u] = ++dep //dfn[]和low[]的初值

    Stack.push(u) //將u壓入棧中

    for each (u,v) in E
    {
        if(v is not visted) //表示結點沒有被訪問過
        {
            Tarjan(v)//繼續向下搜索

            low[u] = min(low[u],low[v])
        }
        else if(v in Stack)//若是v還在棧中
        {
            low[u] = min(low[u],dfn[v])
        }
    }

    if(low[u] == dfn[u])//若是u是強連通的根
    {
        repeat
            v = Stack.pop
            print v
        until (u == v)
    }
}

複雜度分析:若是用鄰接表儲存圖,在Tarjan算法執行的過程當中,每個結點被訪問一次,且只出入棧一次,每條邊也被訪問一次,因此時間複雜度爲O(n+m).ui

相關文章
相關標籤/搜索