Tarjan
課堂補充 by qazwsxedcrfvtg14
https://goo.gl/ZQlWo8
關於Tarjan
• 到底要怎麼唸?
關於Tarjan
• Tarjan症候群
• 第一期,你以為你會了Tarjan
• 第二期,你發現你其實並不會Tarjan
• 第三期,你覺得你真正了解了Tarjan
• 第四期,你發現你還是不會Tarjan
• …
Robert Endre Tarjan
• 1986年圖靈獎得主
• 橋、割點、強連通分量問題、雙連通分量
• Fibonacci heap (斐波那契堆)
• LCA (最近公共祖先)
• Splay Tree (伸展樹)
• …
萬惡之源
重要定義
• Tree Edge = 樹(DFS樹)上的邊,又稱樹枝邊、父子邊。
• Back Edge = 連向祖先的邊,又稱後向邊、返祖邊。(形成環)
• Forward Edge = 連向子孫的邊。
• Cross Edge = 枝葉、樹之間的邊,又稱橫叉邊。(可能形成環)
• Forward Edge 跟 Cross Edge 只會出現在有向圖上
• 連通元件 = 在連通的情況下,點數盡量最多、擴展範圍最大的 一個子圖,又稱連通分量、連通成分、連通單元。
• 當且僅當 = if and only if
重要定義
• dfn[u] = u在樹中被遍歷到的次序號
• DFN = DFS Number = 時間戳記
• low[u] = u或u的子樹中能通過非父子邊追溯到的最早的節點,
即DFS序號最小的節點。
橋
• 一條無向邊(u,v)是橋
• 也就是拔掉這條邊,圖就變成兩塊
• 當且僅當(u,v)爲樹枝邊,且滿足dfn[u]<low[v]
割點
• 一個頂點u是割點
• 也就是拔掉這個點,圖就變成兩塊
• 當且僅當
• u爲樹根,且u有多於一個子樹。
• u不爲樹根,且滿足存在(u,v)爲樹枝邊,使得dfn[u]<=low[v]。
邊 雙連通元件
• 邊雙連通也就是拔掉裡面的任何一條邊圖依然連通。
• 邊雙連通元件則是在邊雙連通的情況下,點數盡量最多、擴展範圍最 大的一個子圖。
• 連接兩個邊雙連通元件的邊剛好就會是橋。
• 只需在求出所有的橋以後,把橋邊刪除,原圖變成了多個連通塊,則 每個連通塊就是一個邊雙連通分支。
• 橋不屬於任何一個邊雙連通分支,其餘的邊和每個頂點都屬於且只屬 於一個邊雙連通分支。
點 雙連通元件
• 點雙連通也就是拔掉裡面的任何一個點圖依然連通。
• 點雙連通元件則是在點雙連通的情況下,點數盡量最多、擴展範 圍最大的一個子圖。
• 標記所有的割點
• 遍歷所有點,但是不要跨過割點,這樣就會得到所有的點雙連通 元件。
點 雙連通元件
• 實際上在求割點的過程中就能順便把每個點雙連通分支求出。
• 建立一個Stack,存儲當前雙連通元件,在DFS時,每找到一條 樹枝邊或後向邊(非橫叉邊),就把這條邊加入棧中。如果遇到某 時滿足dfn[u]<=low[v],說明u是一個割點,同時把邊從棧頂一 個個取出,直到遇到了邊(u,v),取出的這些邊與其關聯的點,
組成一個點雙連通分支。
• 割點可以屬於多個點雙連通分支,其餘點和每條邊只屬於且屬於 一個點雙連通分支。
有向圖 強連通元件
• 強連通是指圖上的任一兩點u,v都存在著從u到v和從v到u的路徑。
• 強連通元件則是在強連通的情況下,點數盡量最多、擴展範圍最 大的一個子圖。
有向圖 強連通元件
• 每個強連通元件爲搜索樹中的一棵子樹。
• 搜索時,把當前搜索樹中未處理的節點加入一個Stack,回溯時 可以判斷棧頂到棧中的節點是否爲一個強連通分量。
• 當dfn[u]=low[u]時,以u爲根的搜索子樹上所有剩餘節點會是 一個強連通元件。
done
• 有其他問題嗎?
Kosaraju
• 先算出這張圖的時間戳記順序
• 把圖所有的邊反向
• 用剛剛的時間戳記順序去DFS,對於一個點,如果可以走到的點 就會跟他屬於同一個強連通塊(但是走過的點不能再走)