轉 tarjan演算法

2022-08-13 19:48:15 字數 1392 閱讀 2877

說到以tarjan命名的演算法,我們經常提到的有3個,其中就包括本文所介紹的求強連通分量的tarjan演算法。而提出此演算法的普林斯頓大學的robert e tarjan教授也是2023年的圖靈獎獲得者(具體原因請看本博「歷屆圖靈獎得主」一文)。

首先明確幾個概念。

強連通圖。在乙個強連通圖中,任意兩個點都通過一定路徑互相連通。比如圖一是乙個強連通圖,而圖二不是。因為沒有一條路使得點4到達點1、2或3。

強連通分量。在乙個非強連通圖中極大的強連通子圖就是該圖的強連通分量。比如圖三中子圖是乙個強連通分量,子圖是乙個強連通分量。

其實,tarjan演算法的基礎是dfs。我們準備兩個陣列low和dfn。low陣列是乙個標記陣列,記錄該點所在的強連通子圖所在搜尋子樹的根節點的dfn值(很繞嘴,往下看你就會明白),dfn陣列記錄搜尋到該點的時間,也就是第幾個搜尋這個點的。根據以下幾條規則,經過搜尋遍歷該圖(無需回溯)和對棧的操作,我們就可以得到該有向圖的強連通分量。

陣列的初始化:當首次搜尋到點p時,dfn與low陣列的值都為到該點的時間。

堆疊:每搜尋到乙個點,將它壓入棧頂。

當點p有與點p』相連時,如果此時(時間為dfn[p]時)p』不在棧中,p的low值為兩點的low值中較小的乙個。

當點p有與點p』相連時,如果此時(時間為dfn[p]時)p』在棧中,p的low值為p的low值和p』的dfn值中較小的乙個。

每當搜尋到乙個點經過以上操作後(也就是子樹已經全部遍歷)的low值等於dfn值,則將它以及在它之上的元素彈出棧。這些出棧的元素組成乙個強連通分量。

由於每個頂點只訪問過一次,每條邊也只訪問過一次,我們就可以在o(n+m)的時間內求出有向圖的強連通分量。但是,這麼做的原因是什麼呢?

tarjan演算法的操作原理如下:

tarjan演算法基於定理:在任何深度優先搜尋中,同一強連通分量內的所有頂點均在同一棵深度優先搜尋樹中。也就是說,強連通分量一定是有向圖的某個深搜樹子樹。

可以證明,當乙個點既是強連通子圖ⅰ中的點,又是強連通子圖ⅱ中的點,則它是強連通子圖ⅰ∪ⅱ中的點。

這樣,我們用low值記錄該點所在強連通子圖對應的搜尋子樹的根節點的dfn值。注意,該子樹中的元素在棧中一定是相鄰的,且根節點在棧中一定位於所有子樹元素的最下方。

強連通分量是由若干個環組成的。所以,當有環形成時(也就是搜尋的下乙個點已在棧中),我們將這一條路徑的low值統一,即這條路徑上的點屬於同乙個強連通分量。

如果遍歷完整個搜尋樹後某個點的dfn值等於low值,則它是該搜尋子樹的根。這時,它以上(包括它自己)一直到棧頂的所有元素組成乙個強連通分量。

tarjan演算法詳解

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

Tarjan 演算法筆記

tarjan演算法 tarjan演算法屬於圖論中的乙個演算法,主要用來求乙個圖中的強連通分量,之後就可以做很多事,比如說縮點 求雙聯通分支等。強連通 在乙個有向圖中,對於幾個點,如果它們能夠互相到達,那麼稱它們強連通。強連通分量 可以這樣理解 把乙個圖里的點分成幾坨,每坨中的點都能夠互相到達 他們強...

Tarjan演算法詳解

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