tarjan求强连通分量的思考
我是按照這里的思路來的。這個博文只是感性理解。
遞歸樹
關于遞歸樹,這篇博文講的很好,我只是給自己總結一下。
定義vis數組,在dfs連通圖時賦予它們不同的含義:
一個連通圖,一定可以表示成一個遞歸樹,加上一些邊。這些邊的種類有:
一個強連通的東西,必定在一棵遞歸樹上,不會分散到多個上。不然那東西就不連通了,想要強連通更是不可能。
對了,如果將dfs訪問到的時間,給遞歸樹上的點編號,一個點的祖先的編號一定比這個點小。
tarjan搞一次出棧的一定是一個強連通的東西
還記得tarjan里,判斷一個點是否出棧的依據嗎?就是\(dfn[u]=low[u]\)。這意味著在u的子結點中,沒有回往u以上的邊,不然\(low[u]<dfn[u]\)。所以根據tarjan算法,如果u出棧,出棧的東西中編號最小的就是u。出棧的東西應該類似于這樣(沒畫有向邊,所以腦補吧):
也就是說,一個節點只有間接連向u,才能和u組成一個強連通的東西。這導致強連通分量在遞歸樹上,其實就是一堆鏈的集合體,也就是樹。
重點來了。如果tarjan搞出來的東西中,有一些點不和其它點強連通,說明它不能間接連向u,而是會間接連向u的一個兒子v。如果\(low[v]<dfn[v]\),這個點又可以間接連向\(low[v]\)...,以此類推,最終連向一個可以出棧的點,那個點u的是兒子。這就證明了,一次出棧搞出來的東西,和u都是強連通的。
tajan一次搞出來的,一定是一個強連通分量
這個標題和前面哪一個的區別是什么呢?就是一個是“東西”,一個是“分量”。分量意味著它大的不能再大了。所以這里要證明(彌天大霧,其實我這個根本不算證明)的,就是一次tarjan搞出來的,最小結點為u的強連通分量中,不會有其它點被遺漏。至于這個證明,我貼一個引用過來:
假設出棧的部分不完整,則本應該在這次出棧的點可能存在于棧的哪些部分呢?
1.之前出棧的部分
2.還沒有入棧的部分
3.還沒有出棧的部分
首先看2,不可能。因為假如沒有入棧,說明這些點沒有在這棵深度優先搜索樹中,假如這些點在本該在該強連通分量中,則和定理1相違背,所以情況2中不可能包含本應該出棧的強連通分量中的點。再看3,也不可能。3中的點的dfn 和 low都分別小于本次出棧的點的dfn和low,也就說明本次出棧的點都無法訪問到還沒有出棧的點,所以情況3中不可能包含本應該出棧的強連通分量中的點。最后看情況1,其實情況1和情況3是類似的,之前出棧的部分A如果和本次出棧的強連通分量B可以組成更大的強連通分量,這就等價于,以之前出棧的強連通分量A為視角,亦是說A是不完整的,A中缺少的部分在還未出棧的節點和還沒有訪問的節點之中。這和之前的情況2,情況3推導矛盾,所以,情況1也不可能。
轉載于:https://www.cnblogs.com/MyNameIsPc/p/7966152.html
總結
以上是生活随笔為你收集整理的tarjan求强连通分量的思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: #161: 给定n*n由0和1组成的矩
- 下一篇: 维生素B2也叫核黄素,在检索这方面的中文