對tarjan縮點/求割點/求橋的理解

不適合初學者,適合複習

縮點

dfn[i]dfn[i]就是一個dfsdfs序。
low[i]low[i]ii不通過ii的父親節點能到達的最高(深度最小/dfsdfs序最小)的祖先節點。
上面兩個數組初始化都是dfsdfs序編號;解釋:dfn[i]dfn[i]顯然,一開始每個點的low[i]low[i]就是自己,也是dfsdfs序。
然後遍歷與之相鄰的點:

  • 如果這個點之前沒被訪問過,就先繼續往下遞歸,回溯回來時用下面點的low[]low[]更新當前這個點的low[]low[],取下面點low[]low[]的最小值,因爲這個點可以走到這些點,按照low[]low[]的定義需要取minmin
  • 如果這個點被訪問過,那就直接用棧裏(已經求出的強連通分量)的點的low[]low[]更新當前點的low[]low[],因爲這個點可以到達這些點(因爲棧裏的點已經是求出的一個強連通分量)。

遍歷完這些點之後如果當前節點的low[]=dfn[]low[]=dfn[],那就說明這個節點的子節點已經沒有返祖邊了,當前點和當前點的子節點都沒有邊指向更早的祖先,所以說這個點當前的強連通分量是最大的(爲什麼求出的強連通分量是最大的)。
記錄從棧裏彈出來的點就是一個強連通分量(環),然後就可以縮點了。
注意圖不一定聯通,所以要對每個沒搜過的點都跑一遍,判斷dfn[]dfn[]是否有值即可。

割點與橋的判斷

割點和橋是對於無向圖而言的。
有割點不一定有橋但有橋一定有割點,可以自己畫圖嘗試一下。
對於割點,如果當前節點frfr的子樹裏有一個節點vv必須通過當前節點frfr才能訪問到frfr的祖先借節點,那麼frfr就是一個割點,因爲去掉frfr之後vv就與frfr上面的點不連通了。
也就是在回溯回來時判斷dfn[fr]<=low[v]dfn[fr]<=low[v],根節點要單獨考慮,看是否有一棵以上子樹即可。
橋與割點只是點與邊的區別,橋就是判斷dfn[fr]<low[v]dfn[fr]<low[v],去掉了相等的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章