Tarjan演算法詳解理解集合

2022-06-01 08:27:14 字數 1431 閱讀 1300

【功能】

tarjan演算法的用途之一是,求乙個有向圖g=(v,e)裡極大強連通分量。強連通分量是指有向圖g裡頂點間能互相到達的子圖。而如果乙個強連通分量已經沒有被其它強通分量完全包含的話,那麼這個強連通分量就是極大強連通分量。

【演算法思想】

用dfs遍歷g中的每個頂點,通dfn[i]表示dfs時達到頂點i的時間,low[i]表示i所能直接或間接達到時間最小的頂點。(實際操作中low[i]不一定最小,但不會影響程式的最終結果)

程式開始時,time初始化為0,在dfs遍歷到v時,low[v]=dfn[v]=time++,

v入棧(這裡的棧不是dfs的遞迴時系統弄出來的棧)掃瞄一遍v所能直接達到的頂點k,如果 k沒有被訪問過那麼先dfs遍歷k,low[v]=min(low[v],low[k]);如果k在棧裡,那麼low[v]=min(low[v],dfn[k])(就是這裡使得low[v]不一定最小,但不會影響到這裡的low[v]會小於dfn[v])。掃瞄完所有的k以後,如果low[v]=dfn[v]時,棧裡v以及v以上的頂點全部出棧,且剛剛出棧的就是乙個極大強連通分量。

【大概的證明】

1.在棧裡,當dfs遍歷到v,而且已經遍歷完v所能直接到達的頂點時,low[v]=dfn[v]時,v一定能到達棧裡v上面的頂點:

因為當dfs遍歷到v,而且已經dfs遞迴呼叫完v所能直接到達的頂點時(假設上面沒有low=dfn),這時如果發現low[v]=dfn[v],棧上面的頂點一定是剛才從頂點v遞迴呼叫時進棧的,所以v一定能夠到達那些頂點。

2 .dfs遍歷時,如果已經遍歷完v所能直接到達的頂點而low[v]=dfn[v],我們知道v一定能到達棧裡v上面的頂點,這些頂點的low一定小於 自己的dfn,不然就會出棧了,也不會小於dfn[v],不然low [v]一定小於dfn[v],所以棧裡v以其v以上的頂點組成的子圖是乙個強連通分量,如果它不是極大強連通分量的話low[v]也一定小於dfn[v](這裡不再詳細說),所以棧裡v以其v以上的頂點組成的子圖是乙個極大強連通分量。

【時間複雜度】

因為所有的點都剛好進過一次棧,所有的邊都訪問的過一次,所以時間複雜度為o(n+m)

【可看證明】

若存在邊且遍歷到它的時候j在棧中,那麼i和j可能存在三種關係:

(1)i是j的祖先;

(2)j是i的祖先;

(3)i和j無前後關係。

對於情況(1),必有dfn[j]>dfn[i],因此不必考慮;

對於情況(2),是逆向邊,顯然i、j處於同乙個強連通分支;

對於情況(3):是橫叉邊。顯然i、j必然在同一棵搜尋樹中(因為搜尋樹的根結點肯定滿足low=dfn),設p=lca(i, j),由於從p到j的路徑上木有low=dfn的結點(否則j已經出棧了),所以j必然可以到達p,又因為p可以到達i,所以j也可以到達i,又因為存在邊,所以i、j處於同乙個強連通分支,這樣就需要在計算low[i]的時候把dfn[j]考慮進去,而不能讓i及其所有後代成為乙個強連通分支。

【外援】

tarjan演算法詳解

參考 tarjan演算法在強連通分量分離中運用很廣,書寫簡單,並且可以拓展到圖的割點,割邊上,十分強大 具體思路 令dfn u 表示當前點的時間戳 low u 表示當前點所能到達的點的時間戳中最小的乙個 到達點u時,將其入棧 拓展點u後代 當且僅當dfn u low u 時,棧頂元素全部出棧,此時出...

Tarjan演算法詳解

tarjan演算法的用途 1.求橋和割點 2.求點和邊的雙連通分量 3.求強連通 targan演算法的流程 利用dfs來遍歷圖來構建一種數型的結構 tarjan演算法的兩個核心陣列 1 對於第一種用途 tarjan演算法原理 我們從1開始遍歷,發現6,5,4的low不小於dfn 3 故3為割點 即4...

Tarjan演算法詳解

在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected components 所以我們在回溯的過程中就能夠通過判...