Tarjan缩点/边双/点双
文章目錄
- 代碼實(shí)現(xiàn)
- 實(shí)際應(yīng)用
- 1.有向圖
- 另外:對于縮點(diǎn)之后的DAG的處理
- 2.無向圖
- 求法
- 細(xì)節(jié)
- 細(xì)節(jié):
- 目錄:
- 1.「POJ 3694」Network
- 2.「2019 ICPC 橫濱站」
- 3. P3225 [HNOI2012]礦場搭建
- 4. 一本通 分離的路徑
代碼實(shí)現(xiàn)
所以其實(shí)就三個(gè)玩意 1.dfn[],low[],indx 2.stack<int>s,bool pd[] 3.scc[],scnt,col[]等我們要求的信息變量名 用處 dfn 記錄當(dāng)前已經(jīng)訪問了幾個(gè)節(jié)點(diǎn) scc 記錄當(dāng)前已經(jīng)有了幾個(gè)強(qiáng)連通分量 dfn[ maxn ] 當(dāng)前節(jié)點(diǎn)是第幾個(gè)被訪問到的 low[ maxn ] 當(dāng)前節(jié)點(diǎn)所能訪問到的最小的 dfn[ ] scc[ maxn ] 記錄各個(gè)節(jié)點(diǎn)所屬于的強(qiáng)連通分量編號 s[ maxn ] 存儲可能構(gòu)成強(qiáng)連通分量的節(jié)點(diǎn)的棧 top 存儲棧頂那么我們?nèi)绻髎cc這樣一個(gè)東西,應(yīng)該是用什么結(jié)構(gòu)呢?
思想其實(shí)并不是很難,就是我們要求SCC,將它放入dfs序中,發(fā)現(xiàn)它有一定的特點(diǎn),那就是在搜索樹中的點(diǎn),一定可以通向祖先,那他們就是一個(gè)scc,因?yàn)樗麄兛梢员舜说竭_(dá)。
所以我們要找最大的scc,那么就是要求出最小的祖先。
所以每個(gè)節(jié)點(diǎn)不用存下所有祖先,而只用存這一個(gè)就夠了。
所以有了low[]來存x的搜索樹內(nèi)邊和最小的點(diǎn)。
那么肯定是要dfs的。
發(fā)現(xiàn)low[]=min(low[son]),min(dfn[to]);
所以dfs回溯遞歸處理,該問題具有自相似性。
實(shí)際應(yīng)用
可以分為兩類
1.有向圖
縮點(diǎn)之后變成了一個(gè)DAG,那么什么時(shí)候應(yīng)該縮點(diǎn)呢,
例子:
“喜歡”是可以傳遞的——如果A喜歡B,B喜歡C,那么A也喜歡C
一旦我們逮捕了一個(gè)間諜,他手中掌握的情報(bào)都將歸我們所有,這樣就有可能逮捕新的間諜,掌握新的情報(bào)。
給定一個(gè) n 個(gè)點(diǎn) m 條邊有向圖,每個(gè)點(diǎn)有一個(gè)權(quán)值,求一條路徑,使路徑經(jīng)過的點(diǎn)權(quán)值之和最大,允許多次通過同一個(gè)點(diǎn)和邊。
從S到T,可以重復(fù)走,求所有路徑中點(diǎn)權(quán)最大值與最小值的差。
P1407 我們已知n對夫妻的婚姻狀況,稱第i對夫妻的男方為Bi,女方為Gi。若某男Bi與某女Gj曾經(jīng)交往過(無論是大學(xué),高中,亦或是幼兒園階段,i≠j),則當(dāng)某方與其配偶(即Bi與Gi或Bj與Gj)感情出現(xiàn)問題時(shí),他們有私奔的可能性。不妨設(shè)Bi和其配偶Gi感情不和,于是Bi和Gj舊情復(fù)燃,進(jìn)而Bj因被戴綠帽而感到不爽,聯(lián)系上了他的初戀情人Gk……一串串的離婚事件像多米諾骨牌一般接踵而至。若在Bi和Gi離婚的前提下,這2n個(gè)人最終依然能夠結(jié)合成n對情侶,那么我們稱婚姻i為不安全的,否則婚姻i就是安全的。
給定所需信息,你的任務(wù)是判斷每對婚姻是否安全。
總結(jié) :可以重復(fù)走,有傳遞性(即一個(gè)接一個(gè))
另外:對于縮點(diǎn)之后的DAG的處理
1.DAG 一定存在一個(gè)或多個(gè)入度為0或出度為0的點(diǎn)。
2.可以進(jìn)行拓?fù)渑判?#xff0c;排序靠后的點(diǎn)不可能到達(dá)靠前的點(diǎn)。
3.DAG上的DP(期望等)
4.把入度為0的點(diǎn)與出度為0的點(diǎn)之間連邊,會變成一個(gè)SCC
2.無向圖
點(diǎn)雙連通:刪去任何一個(gè)點(diǎn)仍然連通邊雙連通:刪去任何一條邊仍然連通(下面會簡稱為“點(diǎn)雙和邊雙”)
另一種定義是,任何兩點(diǎn)之間至少存在兩條不經(jīng)過相同中間點(diǎn)(邊)的路徑如果不滿足雙連通性
割點(diǎn)(割頂):刪去后原圖不連通的頂點(diǎn)集合點(diǎn)雙連通:刪去任何一個(gè)點(diǎn)仍然連通邊雙連通:刪去任何一條邊仍然連通割邊(橋):刪去后原圖不連通的邊集合求法
- 不需要用到棧,因?yàn)椴挥么鎯?qiáng)連通分量。
- 割邊一定存在于樹邊上,否則存在另一條路徑。
- 注意low的定義有所變化,有向圖中l(wèi)ow只代表能到達(dá)的在棧中的節(jié)點(diǎn)的最小值。但在無向圖中,沒有棧的限制。
- dfn[u]<low[v]那么(u,v)即為割邊
細(xì)節(jié)
- 注意這里變成了嚴(yán)格小于,因?yàn)槲覀兿拗屏酥赶蚋赣H的邊,那么若low等于dfn的話相當(dāng)于存在一條回路。
- 但是要進(jìn)行特判不能讓出去的點(diǎn)再次走同一個(gè)無向邊,否則low[to]必定等于dfn[x],沒有意義了,但是還要允許重邊訪問,所以我們應(yīng)該記錄邊的編號。
- 對于搜索樹中的根節(jié)點(diǎn),兒子數(shù)大于等于2即為割點(diǎn)。
- 對于一般點(diǎn):dfn[u]<=low[v]那么u就是割點(diǎn)
- 但是注意割邊兩邊一般是割點(diǎn),但是特殊情況下一邊只有一個(gè)點(diǎn),那就不是割點(diǎn)了。
細(xì)節(jié):
- 引入了rt,son每次tarjan都要重新賦值。
- 小心pd[]=true,cnt++;這樣的語句,因?yàn)閎ool值本來可能已賦值過了。
- 分類討論!!!不要忘了。
目錄:
- 邊雙縮點(diǎn)變成樹,在線查詢兩點(diǎn)之間邊的個(gè)數(shù),然后再一次縮點(diǎn)。
- 邊雙在指定無向邊的方向之后一定可以變成強(qiáng)連通分量。
1.「POJ 3694」Network
在線查詢一個(gè)無向圖,加入一條邊后減少了多少條橋。
2.「2019 ICPC 橫濱站」
給出一些起點(diǎn)和終點(diǎn),判定把無向邊確定方向之后能否滿足每一個(gè)起點(diǎn)都可以走到對應(yīng)的終點(diǎn)。
3. P3225 [HNOI2012]礦場搭建
題意:對于一個(gè)礦場可視作無向圖,現(xiàn)在已知任意礦場塌陷后,每一個(gè)點(diǎn)可以從出口逃出,那么最少在圖上建立幾個(gè)出口及方案數(shù)。
那么可以發(fā)現(xiàn)刪去一個(gè)點(diǎn)對于點(diǎn)雙仍然聯(lián)通,所以dfs每一個(gè)點(diǎn)雙,統(tǒng)計(jì)點(diǎn)雙中有多少割點(diǎn)。
可以發(fā)現(xiàn),如果將點(diǎn)雙視為點(diǎn),那么圖會變成一個(gè)樹,如果斷掉一個(gè)割點(diǎn),相當(dāng)于斷裂一條邊,所以只要在葉子節(jié)點(diǎn)上建立就可以了。
- 若沒有割點(diǎn)則建立一個(gè),方案數(shù)為節(jié)點(diǎn)數(shù)。
- 若有一個(gè)割點(diǎn)則需要建立一個(gè)在非割點(diǎn)上,方案數(shù)為非割點(diǎn)的數(shù)目。
- 若有兩個(gè)割點(diǎn)則不需要建立。
4. 一本通 分離的路徑
給出一個(gè)無向連通圖,現(xiàn)在求出使每個(gè)點(diǎn)到其他點(diǎn)都有兩條完全不同的路徑最少還需要添加幾條邊。
可以發(fā)現(xiàn)這就是一個(gè)邊雙,那么對邊雙縮點(diǎn),圖會變成一個(gè)樹,那么只要給兩個(gè)葉子節(jié)點(diǎn)連邊再縮點(diǎn),就可以使新的樹葉子數(shù)減少二,所以共用(sum-1)/2。
注意各個(gè)題解都沒有注意到的是,如果兩個(gè)普通兩個(gè)葉子相連只能減少一個(gè)葉子,因?yàn)槿绻麄兊膌ca有兩個(gè)兒子就會在他們的lca處新增一個(gè)葉子。所對葉子節(jié)點(diǎn)的選取是有要求的。
總結(jié)
以上是生活随笔為你收集整理的Tarjan缩点/边双/点双的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 生姜能促进毛发生长吗
- 下一篇: P4126 [AHOI2009]最小割(