關節點及重連通圖
阿新 • • 發佈:2019-02-02
這個內容為什麼想放在這個時候就放出來呢?因為剛剛才把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排序裡是不是也說過?』,所以程式碼就不過多解釋。