計算圖的關節點


圖的關節點:

  如果刪去某個節點及依附在該節點上的邊后,該圖被分割為兩個或兩個以上的連通圖,則該節點為關節點。

計算關節點的關鍵思路:

  在該圖的深度優先生成樹上,如果某個節點的孩子節點(不一定是二叉樹,孩子節點可能大於2)的子樹中,所有孩子節點的子樹中都有回邊能回到該節點的祖先上,則該節點不是關鍵節點,因為即使刪除了該節點,該節點的祖先或它的孩子都能通過回邊將彼此連結起來。與之對應,如果該節點的孩子節點中,但凡有一個孩子節點的子樹中沒有回邊,則該節點一定為關鍵節點,因為即使其他的孩子節點都有回邊,但刪除該節點后,這個沒有回邊的孩子節點還是與被刪節點的祖先間分割開了。

一點不是問題的問題:

  對於當前節點v,在不考慮v是整個樹的根節點的情況下,v只有在它的某一個子樹w中,w及w的子節點里不存在到v的父母或祖先節點的回邊的情況下,v才是關鍵節點(只有在v的所有的孩子節點的子樹上都有回邊才不算關鍵點,P177中,G5的B只有在C上才有回邊,因此B仍然為關鍵節點)。

  現在對low(v):

Low(v)在visited[v],low[w],visited[k]中找最小值,w為v的孩子節點,k為與v有回邊的父母或祖先節點。

首先看vistited[v],對visited[v]來說,它是v的被訪問順序,由於訪問時使用的前序遍歷,因此越靠近葉子節點的節點visited值越大。

再看low[w],low[w]是用於統計v的孩子節點的回邊的情況的,現在加入v沒有回邊回到它的祖先的回邊,但如果它的子節點w有或w的子節點里有,則等價於v也有了這個回邊,因為v可以通過w來訪問到v的祖先。

  對於visited[k],這個用於統計v到祖先的回邊。

Low(v)的過程,實際上就是比較visited[v],low[w],visited[k]的大小,如果low[w]最小,說明v的子節點w的子樹中有回邊到v的祖先,如果visited[k]最小,說明v有到v的祖先的回邊。

計算得到的low(v),是用於判斷v的父親節點是否為關鍵節點的,因為low(v)是v所能到達的最淺的節點,它要么是它被訪問的順序(visited[v]),要么是通過子樹回邊到達的最淺節點(low(w)),要么是通過自己的回邊到達的最淺節點(visited[k])。

對一個節點,當它的孩子節點的最淺節點小於它的被訪問順序,也就是low[w]<visited[v]時,說明v的孩子節點中有回邊繞過了v到達了v的祖先。如果v的所有孩子節點都有這樣的回邊,則刪除v后祖先節點一樣能通過回邊訪問到v的孩子,而不影響連通性。

而如果只要有一個孩子節點使low[w]>=visited[v],也就是代表該孩子節點無法繞過v,則v就是關鍵節點,因為祖先節點無法繞過v訪問這個孩子。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM