強聯通分量之kosaraju算法
首先定義:強聯通分量是有向圖G=(V, E)的最大結點集合,滿足該集合中的任意一對結點v和u,路徑vu和uv同時存在。
kosaraju算法用來尋找強聯通分量。對於圖G,它首先隨便找個結點dfs,求出每個節點最後一次訪問的時間戳f(x),然後我們建立反圖Gt,接著根據倒序的時間戳來dfs每個節點,每次dfs到的結點集合就是一個強聯通分量。事實上這個算法的思想和拓撲排序類似。
我們來證明它(註意這裏面的圖指原圖,而不是反圖):
引理:對於G中的兩個強聯通分量C和C’,若點u屬於C,點v屬於C‘,且存在邊(u,v),那麽f(C)>f(C‘)。
證明應該很好想。。如果先訪問C,那麽一定會先訪問完C‘再訪問C。如果先訪問C’,因為強聯通分量的性質,C一定不在C’的深度優先搜索樹中。
推論:對於G中的兩個強聯通分量C和C’,若點u屬於C,點v屬於C‘,如果f(C)>f(C‘),那麽不可能存在邊(v,u)
因為若有邊(v,u),訪問C‘一定會訪問到C,然後C先退出。如果先訪問C,那麽f(C)依舊小於f(C’)
證明:若根據倒序的時間戳dfs結點,那麽最後一個結點一定屬於最後一個結束訪問的強聯通分量C‘(因為C’被訪問到的次序就是由最後一個結點的時間戳決定的),也就是f(C‘)>f(任意一個C)。根據推論,在原圖中不可能存在邊,從其它強聯通分量連向它。也就是對於反圖來說,從當前結點dfs只會dfs到最後一個結束訪問的強連通分量。接著,倒序找到第二個沒有被訪問過的點,它屬於倒數第二個結束訪問的強聯通分量,並且按原圖來看,只可能有前面訪問過的強聯通分量向它連邊,所以它只能訪問自己所屬的強聯通分量。以此類推,可以證明算法的正確性。
這個證明的重點在於:目前倒序來看,最先沒有訪問過的點屬於新的待處理強聯通分量。
強聯通分量之kosaraju算法