1、相關概念
強連通圖:在乙個強連通圖中,任意兩個點都通過一定路徑互相連通。
強連通分量:在乙個非強連通圖中極大的強連通子圖就是該圖的強連通分量。
2、偽**
algorithm tarjan isinput: 圖 g = (v, e)
output: 以所在的強連通分量劃分的頂點集
index := 0
s := empty // 置棧為空
for each v in v do
if (v.index is undefined)
strongconnect(v)
end if
function strongconnect(v)
// 將未使用的最小index值作為結點v的index
v.index := index
v.lowlink := index
index := index + 1
s.push(v)
// 考慮v的後繼結點
for each (v, w) in e do
if (w.index is undefined) then
// 後繼結點w未訪問,遞迴呼叫
strongconnect(w)
v.lowlink := min(v.lowlink, w.lowlink)
else if (w is in s) then
// w已在棧s中,亦即在當前強連通分量中
v.lowlink := min(v.lowlink, w.index)
end if
// 若v是根則出棧,並求得乙個強連通分量(其實滿足等式之後,v和呼叫他的父節點之間的邊就是割邊)
if (v.lowlink = v.index) then
start a new strongly connected component
repeat
w := s.pop()
add w to current strongly connected component
until (w = v)
output the current strongly connected component
end if
end function
3、關於演算法思想和**的解釋
for each (v, w) in e do這一段不難理解,如果v訪問到的點從未被訪問過,那麼需要遞迴計算這個點的屬性,然後將w所能訪問到的最小屬性的點的序號和自己已經記錄下來的能訪問到的最小節點的序號比較,誰小取誰。if (w.index is undefined) then
// 後繼結點w未訪問,遞迴呼叫
strongconnect(w)
v.lowlink := min(v.lowlink, w.lowlink)
else if (w is in s) then
// w已在棧s中,亦即在當前強連通分量中
v.lowlink := min(v.lowlink, w.index)
end if
如果這個點已經訪問過而且已經在棧中,那麼表示是同乙個強連通分量,比較w.index和v.lowlink取小的作為v.lowlink,如果w.index小,那麼已經排除v是強連通分量的根的可能性,如果是v.lowlink小,由於是按照順序排的,所以v.index不會出現的,因為如果後來的點可以訪問到祖先,那麼w怎麼可能被當做是乙個強連通分量的元素而已經出棧呢?
經過上面的過程結束對v.lowlink的求值,判斷它是不是根,如果是的話,那麼表示下乙個強連通分量已經開始,這個點上面的所有點都應該被彈出作為乙個強連通分量
tarjan 演算法 求強連通分量)
全網最詳細tarjan演算法講解,我不敢說別的。反正其他tarjan演算法講解,我看了半天才看懂。我寫的這個,讀完一遍,發現原來tarjan這麼簡單!tarjan演算法,乙個關於 圖的聯通性的神奇演算法。基於dfs 迪法師 演算法,深度優先搜尋一張有向圖。注意!是有向圖。根據樹,堆疊,打標記等種種神...
Tarjan演算法求強連通分量
有向圖強連通分量的tarjan演算法 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected component...
Tarjan演算法求強連通分量
有向圖強連通分量的tarjan演算法 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected component...