1. 程式人生 > >[圖] 3.2.2 Tarjan演算法-有向圖的強連通分量

[圖] 3.2.2 Tarjan演算法-有向圖的強連通分量

Tarjan演算法

【Tarjan演算法】基於對圖DFS的演算法,每個強連通分量為搜尋樹中的一棵子樹

【輔助資料結構】

  1. DFN[u]:為節點u搜尋的次序編號(時間戳)
  2. Low[u]:u或u的子樹能夠追溯到的最早棧中結點的次序號
Low(u)=Min {
    DFN(u),
    Low(v), (u,v)為樹枝邊,u為v的父節點
    DFN(v), (u,v)為指向棧中節點的後向邊(非橫叉邊)
} //三個值的最小值

【特殊情況】DFN(u)=Low(u):以u為根的搜尋子樹上所有節點是一個強連通分量。搜尋時,把當前搜尋樹中未處理的節點加入一個堆疊,回溯時可以判斷棧頂到棧中的節點是否為一個強連通分量

tarjan(u) { //虛擬碼
    DFN[u]=Low[u]=++Index                      // 為節點u設定次序編號和Low初值
    Stack.push(u)                              // 將節點u壓入棧中
    for each (u, v) in E                       // 列舉每一條邊
        if (v is not visted)               // 如果節點v未被訪問過
            tarjan(v)                  // 繼續向下找
            Low[u] = min(Low[u], Low[v])
        else if (v in S)                   // 如果節點v還在棧內
            Low[u] = min(Low[u], DFN[v])
    if (DFN[u] == Low[u])                      // 如果節點u是強連通分量的根
        repeat
            v = S.pop                  // 將v退棧,為該強連通分量中一個頂點
            print v
        until (u== v)
}