tarjan求割邊割點

2022-05-01 01:03:13 字數 2939 閱讀 8003

內容及**來自

割邊:在連通圖中,刪除了連通圖的某條邊後,圖不再連通。這樣的邊被稱為割邊,也叫做橋。

割點:在連通圖中,刪除了連通圖的某個點以及與這個點相連的邊後,圖不再連通。這樣的點被稱為割點。

dfs搜尋樹:用dfs對圖進行遍歷時,按照遍歷次序的不同,我們可以得到一棵dfs搜尋樹。

樹邊:在搜尋樹中的藍色線所示,可理解為在dfs過程中訪問未訪問節點時所經過的邊,也稱為父子邊

回邊:在搜尋樹中的橙色線所示,可理解為在dfs過程中遇到已訪問節點時所經過的邊,也稱為返祖邊、後向邊

觀察dfs搜尋樹,我們可以發現有兩類節點可以成為割點。對根節點u,若其有兩棵或兩棵以上的子樹,則該根結點u為割點;對非葉子節點u(非根節點),若其中的某棵子樹的節點均沒有指向u的祖先節點的回邊,說明刪除u之後,根結點與該棵子樹的節點不再連通;則節點u為割點。對於根結點,顯然很好處理;但是對於非葉子節點,怎麼去判斷有沒有回邊是乙個值得深思的問題。我們用dfn[u]記錄節點u在dfs過程中被遍歷到的次序號,low[u]記錄節點u或u的子樹通過非父子邊追溯到最早的祖先節點(即dfs次序號最小),那麼low[u]的計算過程如下。

對於給的例子,其求出的dfn和low陣列如下。

id     123456

dfn   123456

low   111444

可以發現,對於情況2,當(u,v)為樹邊且low[v]≥dfn[u]時,節點u才為割點。而當(u,v)為樹邊且low[v]>dfn[u]時,表示v節點只能通過該邊(u,v)與u連通,那麼(u,v)即為割邊。tarjan演算法的時間複雜度是o(n+m)的,非常快。

以hihocoder1183為例給出**:

1 #include2 #include3 #include4

using

namespace

std;

5int n,m,order=0;6

int low[20004],dfn[20004],father[20004],son[20004];7

//father:父結點 son:子結點個數

8 vector cutpoint,edge[20004

];9 vector< pair >cutedge;

1011

void tarjan(int

u)12

29else

if(v!=father[u]) low[u]=min(low[u],dfn[v]);30}

31//

根節點若有兩棵或兩棵以上的子樹則該為割點

32//

非根節點若所有子樹節點均沒有指向u的祖先節點的回邊則為割點

33if((father[u]==0&&son[u]>1)||(father[u]&&flag)) cutpoint.push_back(u);34}

3536

intmain()

3745 tarjan(1

);46

sort(cutedge.begin(),cutedge.end());

47sort(cutpoint.begin(),cutpoint.end());

48if(0==cutpoint.size()) puts("

null");

49else

5055

for(int i=0;i"

%d %d\n

",cutedge[i].first,cutedge[i].second);

56 }

view code

1 #include2 #include3 #include4

#define n 420000

5using

namespace

std;

6 vectorcutpoint;

7 vectorint,int> >cutedge;

8int

next[n],to[n],num,head[n],dfn[n],low[n],tim,son[n],father[n],n,m,a,b;

9bool

flag;

10void add(int false_from,int

false_to)

15void dfs(int

x)29

else

30if(father[x]!=to[i])

31 low[x]=min(low[x],dfn[to[i]]);32}

33if((!father[x]&&son[x]>1)||(father[x]&&flag))

34cutpoint.push_back(x);35}

36int

main()

43 dfs(1

);44

sort(cutpoint.begin(),cutpoint.end());

45sort(cutedge.begin(),cutedge.end());

46 printf("

%d",cutpoint[0

]);47

for(int i=1;i)

48 printf("%d"

,cutpoint[i]);

49 printf("\n"

);50

for(int i=0;i)

51 printf("

%d %d\n

",cutedge[i].first,cutedge[i].second);

52return0;

53 }

view code

tarjan演算法求割點割邊

在上一節我們已經知道tarjan演算法可以求聯通圖,在這裡我們也運用tarjan的思想求割點與割邊,首先我們先來說說割點,那麼什麼事割點呢,先來看一張圖 a 來自網路 在 a 圖中,我們將a點以及與a點相連的邊全部去除,會發現這個聯通圖被分成了倆個聯通圖,乙個是節點f,另外乙個是餘下的所有的節點組成...

tarjan求割點和割邊

概念 割點 在乙個無向圖中,如果刪除某個頂點,這個圖就不再連通 任意兩點之間無法相互到達 那麼這個頂點就是這個圖的割點。割邊 橋 在乙個無向圖中刪除某條邊後,圖不再連通,那麼這條邊就是這個圖的割邊 也叫作橋 求法 x 為樹根,且 x 有多於乙個子樹。x 不為樹根,且滿足 x 為 to 在搜尋樹中的父...

割點 割邊 tarjan

洛谷割點模板題 傳送門 割邊 在連通圖中,刪除了連通圖的某條邊後,圖不再連通。這樣的邊被稱為割邊,也叫做橋。割點 在連通圖中,刪除了連通圖的某個點以及與這個點相連的邊後,圖不再連通。這樣的點被稱為割點。dfs搜尋樹 用dfs對圖進行遍歷時,按照遍歷次序的不同,我們可以得到一棵dfs搜尋樹。樹邊 在搜...