Tarjan 复习小结
總算把這幾個東西策清楚了。
- 在\(Tarjan\)算法里面,有兩個時間戳非常重要,一個是\(dfn\),意為深度優(yōu)先數(shù),即代表訪問順序;一個是\(low\),意為通過反向邊能到達的最小\(dfn\),也就是最強反祖能力。
注意,強聯(lián)通分量只存在于有向圖中,割點,橋,點雙,邊雙是無向圖的概念。
一、割點。
- [x] 模板題
- 割點:一個結(jié)點稱為割點,當(dāng)且僅當(dāng)去掉該節(jié)點和其相關(guān)的邊之后的子圖不連通。
- 針對無向圖。
- 首先我們考慮一個連通圖(非連通圖可以分別考慮連通塊),我們從任意一個起點開始進行深度優(yōu)先搜索,可以得到一棵樹,并且這棵樹中所有結(jié)點的子樹之間不存在邊,即沒有跨越兩棵子樹的邊
- 考慮一下,如果存在,那么與深度優(yōu)先搜索樹的定義互相矛盾。
于是有如下定理:
在無向連通圖\(G\)中,
1、根結(jié)點\(u\)為割頂當(dāng)且僅當(dāng)它有兩個或者多個子結(jié)點;
2、非根結(jié)點\(u\)為割頂當(dāng)且僅當(dāng)u存在結(jié)點v,使得\(v\)與其所有后代都沒有反向邊可以連回\(u\)的祖先。可以簡單寫成\(dfn_u\leq low_v\)- 貼個代碼
二、橋。
- 針對無向圖。
- 橋的求法其實也是類似的,它的求法可以看成是割頂?shù)囊环N特殊情況.
- 當(dāng)結(jié)點\(u\)的子結(jié)點\(v\)的后代通過反向邊只能連回\(v\),那么刪除這條邊\((u, v)\)就可以使得圖\(G\)非連通了。用\(Tarjan\)算法里面的時間戳表示這個條件,就是\(low_v>dfn_u\)。
- 注意更新\(low\)時是特判不能使用來的反邊。
- 不需要單獨考慮根節(jié)點的情況。
- 貼個代碼
三、強聯(lián)通和雙聯(lián)通一點區(qū)別。
鏈接
所謂雙連通與強連通,最大的差別,也是最本質(zhì)的差別就是后者適用于無向圖中,而前者適用于有向圖。至于兩者的概念是一樣的,就是圖中有a點、b點,從a點可到達b點,同時從b點可到達a點。
四、強聯(lián)通分量。
- 而為了存儲整個強聯(lián)通分量,這里挑選的容器是棧。
- 每次一個新節(jié)點出現(xiàn),就進,如果這個點有出度就繼續(xù)往下找。
- 每次返回上來都看一看子節(jié)點與這個節(jié)點的\(low\)值,誰小就取誰,保證最小的子樹根。
- 如果找到\(low==dfn\),說明這個節(jié)點是這個分量的根節(jié)點。
最后找到分量的節(jié)點后,就將這個棧里,它們就組成一個全新的分量。
- 具體實現(xiàn)的時候,如果這條邊是往下的邊,就用他的\(low\)去更新現(xiàn)在的\(low\)
否則,如果這條邊指向了棧內(nèi)的點,就用他的\(dfn\)去更新現(xiàn)在的\(low\)
為什么要特別判斷是否是棧內(nèi)的點呢?因為只有棧內(nèi)的點才可以到達當(dāng)前點。在有向圖中,如果指向的點不在棧內(nèi),他也就無法到達當(dāng)前點,不可能組成強聯(lián)通。
判斷\(low==dfn\)是在\(for\)循環(huán)外面進行的。
- 貼個代碼
五、邊雙。
- 其實就是一個求橋的過程。
- 一個橋把聯(lián)通塊分成了兩個部分,這兩個部分是獨立的兩個邊雙。
- 貼個代碼
upd on 10.31
- 另外一種寫法:
- 或者類似于有向圖的強聯(lián)通分量,區(qū)別在于:
- 強制不走回頭路。
- 不需要考慮是否在棧內(nèi)。
六、點雙
- 其實就是一個求割點的過程。
- 一個割點把聯(lián)通塊分成了兩個部分,這兩個部分是獨立的兩個點雙。
- 貼個代碼
和割點的代碼是一樣的,只是最后\(Dfs\)找到所有點雙,注意,一個割點會存在于多個點雙內(nèi)。
七、小清新水題。
- [x] 割點模板題
- [x] 橋模板題
- [x] 有向圖強聯(lián)通分量模板
[x] 無向圖邊雙模板
其他題目在yl題單了。
轉(zhuǎn)載于:https://www.cnblogs.com/Tyher/p/9843020.html
總結(jié)
以上是生活随笔為你收集整理的Tarjan 复习小结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最小生成树 次小生成树
- 下一篇: [School Life - Study