1. 程式人生 > >關節點及重連通圖

關節點及重連通圖

這個內容為什麼想放在這個時候就放出來呢?因為剛剛才把TOP排序講完,所以我們跳過關鍵路徑『有什麼關聯嗎?』,直接進入關節點和重連通圖。
一、關節點:又稱割點,是維繫一個圖能夠連通的節點(就是說沒有這個節點,這個圖就不連通),若從連通圖中刪除點V,就會使這個圖割裂成多個子圖,則稱V點為該圖的關節點。
二、重連通圖:沒有關節點的圖。【補充:其充分必要條件為任意兩點都在一個圈上!】

以上是這兩個重點的概念,詳情請見百度百科
接下來就是重點了!

三、DF生成樹(不是DFS又是DFS『糾結』):對圖DFS,若沿某條邊所到達的點是一個未訪問的節點,則稱這條邊為樹邊,而由樹邊構成的生成樹,稱為DF生成樹。

四、實現:
1.變數定義:

  • dfn[v]——v點的深搜編號
  • low[v]——是從v點出發的所有路徑中,所能到達的點的dfn最小值
  • low[v]=min(dfn[v],min(low[son],low[father])),這個具體看實現!
    2.核心思想:
  • 對圖DFS,計算low[v]
  • 判關節點,若v為根,則當v的子樹個數≥2時,v是關節點。
  • 若v不為根,則當v的某個子節點s的low[s]≥dfn[v],v是關節點。
  • 最後輸出相應的重連通子圖。

3.程式碼:

void out(int v){
    while(s[p]!=v){
        printf("%4d",s[p]);p--;
    }
    printf("%4d\n"
,v); } void dfs(int i){ dfn[i]=++v;int u; low[i]=v;s[++p]=i; for(u=1;u<=n;u++) if(g[i][u]) if(!dfn[u]){ dfs(u); low[i]=min(low[i],low[u]); if(low[u]>=dfn[i]){ if(i==1)x++; else
k[i]=1; out(i); } } else low[i]=min(low[i],dfn[u]); }

這段程式碼和其實現思想是完全一樣的『TOP排序裡是不是也說過?』,所以程式碼就不過多解釋。