Tarjan算法詳解
今天偶然發現了這個算法,看了好久,終於明白了一些表層的知識、、、、在這里和大家分享一下。。。
Tarjan算法是一個求解極大強聯通子圖的算法,相信這些東西大家都在網絡上百度過了,這里不再贅述。
在這個算法中,定義了兩個數組,一個是dfn數組,一個是low數組,相信大家在這里就暈了(我也暈了、、),不過自己模擬了幾次算法執行過程之后,就理解了這個算法的意思,如果大家不明白,也可以這樣做
我覺得突破點主要在dfn數組和low數組的含義該如何詮釋:
dfn數組: 意思就是在dfs的過程中,當前的這個節點是第幾個被訪問的
low數組: 有些並查集的意思,就是在dfs的過程中,標記如果當前節點是極大強聯通子圖的話,他的根節點的標號就是對應的low值:
如果下一個要遍歷的節點在棧中,那么就要把當前節點的low值設置成 下一個節點(在棧中)的dfn值,dfn值是什么呢?就是記錄這個節點是第幾個被遍歷到的。
如果下一個要遍歷的節點不再棧中,那么就要把當前節點的low值設置成下一個節點和當前節點的low值中最小的那個。
如果還是不太明白,仔細看兩遍把、、、、要不然還可以看看下面的模擬過程吧:
(1)假如從1號節點開始遍歷,開始dfs,並不斷設置當前節點的dfn值和low值,並壓入棧中,那么第一次在6處停止,因為6沒有出度。那么此時的dfn和low值分別為:(初始化所有的low和dfn為0)
節點: 1 2 3 4 5 6
dfn: 1 0 2 0 3 4
low: 1 0 2 0 3 4
棧: 1 3 5 6
(2)6號節點沒有能出邊了,那么6號節點自己就成為一個極大強聯通子圖,彈出6,對5來說,6被訪問過了,所以它也沒有能訪問的邊了,那么5 也是一個極大強聯通子圖,彈出5
(3)現在模擬指針在3的位置,3遍歷到4,四再遍歷1號節點,因為1號節點還在棧中,那么就代表着棧中的現有的所有元素構成了一個強聯通圖(仔細想想、、),而且4號節點訪問到了1號節點,那么就把low[4]的值設置為1號節點的根吧(low[1])那么現在的low[4] = 1(代表着4的根節點是1),再接着訪問4的下一個子節點,6號節點,而6已經被訪問過了,所以退出循環,退到3號節點處,3號節點也沒有能訪問的下一個節點了,退回到1號節點處。
(4)現在訪問1號節點的下一個能訪問的節點,2號節點,然后再訪問4號節點,因為4號節點現在在棧中,那么還是像剛才一樣,把二號節點的low值設置成4號節點的根(low[4]),現在,退回到1,遍歷結束。
現在棧中有元素1,3,4,2,剩下的就是極大強聯通子圖了。。。
網上有許多詳解Tarjan算法的例子,如果剛才我描述的還是看不懂,可以參見http://wenku.baidu.com/view/112c64096c85ec3a87c2c527.html?re=view