Tarjan求割點 橋

2022-09-08 18:57:09 字數 1496 閱讀 9800

概念

1.橋:是存在於無向圖中的這樣的一條邊,如果去掉這一條邊,那麼整張無向圖會分為兩部分,這樣的一條邊稱為橋無向連通圖中,如果刪除某邊後,圖變成不連通,則稱該邊為橋。

2.割點:無向連通圖中,如果刪除某點後,圖變成不連通,則稱該點為割點。

割點特點:1)當前節點為樹根的時候,條件是「要有多餘一棵子樹」(如果這有一顆子樹,去掉這個點也沒有影響,如果有兩顆子樹,去掉這點,兩顆子樹就不連通了。)

2)當前節點u不是樹根的時候,條件是「low[v]>=dfn[u]」,也就是在u之後遍歷的點,能夠向上翻,最多到u,(如果能翻到u的上方,那就有環了,去掉u之後,圖仍然連通。)

橋的特點:若是一條無向邊(u,v)是橋,

1)當且僅當無向邊(u,v)是樹枝邊的時候,需要滿足dfn(u)注意點:

1)求橋的時候:因為邊是無方向的,所以父親孩子節點的關係需要自己規定一下,

在tarjan的過程中if(v不是u的父節點) low[u]=min(low[u],dfn[v]);

因為如果v是u的父親,那麼這條無向邊就被誤認為是環了。

2)找橋的時候:注意看看有沒有重邊,有重邊的邊一定不是橋,也要避免誤判。

也可以先進行tarjan(),求出每乙個點的dfn和low,並記錄dfs過程中的每個點的父節點,遍歷所有點的low,dfn來尋找橋和割點

(dfn[u]表示u點第一次訪問到的時間戳,low[u],表示以及u的子孫所能到達的最小時間戳)

#includeusing

namespace

std;

#include

#include

#include

#define n 201vector

g[n];

intn,m,low[n],dfn[n];

bool

is_cut[n];

intfather[n];

int tim=0

;void tarjan(int i,int

father)

else

if(father!=k)/*

假如k是i的父親的話,那麼這就是無向邊中的重邊,有重邊那麼一定不是橋

*/low[i]=min(low[i],dfn[k]);//

dfn[k]可能!=low[k],所以不能用low[k]代替dfn[k],否則會上翻過頭了。}}

intmain()

memset(dfn,-1,sizeof

(dfn));

memset(father,

0,sizeof

(father));

memset(low,-1,sizeof

(low));

memset(is_cut,

false,sizeof

(is_cut));

int rootson=0

; tarjan(

1,0);

for(int i=2;i<=n;++i)

return0;

}

tarjan求割點和橋(割邊)

tarjan求割點和橋 例題 割點 重要的地方在 中都有注釋 include define ll long long using namespace std const ll m 2e4 10,maxn 3e6 30 int dfn m low m tot int e m 1 k,p m k2 ve...

Tarjan演算法求橋和割點

預備定義 low u 定義為u或者u的子樹中能夠通過 非父子邊 追溯到的最早的節點的dfs開始時間 d u 表示dfs過程中u的進棧時間 割點 無向連通圖中,如果刪除某點後,圖變成不連通,則稱該點為割點。橋 無向連通圖中,如果刪除某邊後,圖變成不連通,則稱該邊為橋。判斷割點方法 1 u為樹根,且u有...

tarjan求橋 割頂

若low v dfn u 則 u,v 為割邊。但是實際處理時我們並不這樣判斷,因為有的圖上可能有重邊,這樣不好處理。我們記錄每條邊的標號 一條無向邊拆成的兩條有向邊標號相同 記錄每個點的父親到它的邊的標號,如果邊 u,v 是v的父親邊,就不能用dfn u 更新low v 這樣如果遍歷完v的所有子節點...