《學習筆記》 tarjan 求割點(割頂)

2022-08-13 22:36:18 字數 1615 閱讀 5340

go to the problem

割點:在乙個無向圖中,如果有乙個頂點集合,刪除這個頂點集合以及這個集合中所有頂點相關聯的邊以後,圖的連通分量增多,就稱這個點集為割點集合。

如果某個割點集合只含有乙個頂點x(也即是乙個割點集合),那麼x稱為乙個割點。

割點

給出乙個n個點,m條邊的無向圖,求圖的割點。

輸入格式:

第一行輸入n,m

下面m行每行輸入x,y表示x到y有一條邊

輸出格式:

第一行輸出割點個數

第二行按照節點編號從小到大輸出節點,用空格隔開

輸入樣例#1:

6 7

1 21 3

1 42 5

3 54 5

5 6

輸出樣例#1:

1 

5

n,m均為100000

tarjan 圖不一定聯通!!!

注意與tarjan 求強連通分量的方法區別。

求割點不需要用到棧。

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;78

int n,m,x,y,cnt,index,ans=0;9

int first[100010],next[200010

];10

int dfn[100010],low[100010

];11

bool del[100010

];12

13struct

maplerode[200010

];16

17void build(int f,int

t)18

;20 next[cnt]=first[f];

21 first[f]=cnt;22}

2324

void tarjan(int n,int

fa)25

38 else if(rode[i].t!=fa) low[n]=min(low[n],dfn[rode[i].t]);39}

40if(fa==-1&&cd>=2) del[n]=1; //

如果n為根且n的子樹數量大於等於 2 ,即為乙個割點 41}

42int

main()

4351

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

52if(!dfn[i]) tarjan(i,-1

);53

for(int i=1;i<=n;++i) if(del[i]) ++ans;

54 printf("

%d\n

",ans);

55for(int i=1;i<=n;++i)

56if

(del[i])

57 printf("

%d "

,i);

58return0;

59 }

割點割頂tarjan

原題 首先tarjan求割點的重點就是dfn和low陣列的理解。dfn i 就是時間戳,即在什麼時刻搜尋到了點i,low i 則是i點能回溯到的dfn最小的祖先,搜尋的時候判斷一下當對於點x存在兒子節點y,使得dfn x low y 則x一定是割點。因為只要x的子節點不能回溯到x的上面,就是沒有返祖...

學習筆記 tarjan求割點

都口胡了 求割邊,就順便口胡 求割點好了qaq 的定義同 求有向圖強連通分量.列舉當前點 的所有鄰接點 1.如果某個鄰接點 未被訪問過,則訪問 並在回溯後更新 2.如果某個鄰接點 已被訪問過,則更新 對於當前節點 如果 為搜尋樹中的根節點,若它的子節點數 根是多棵子樹上節點的唯一連通方式 則 為割點...

tarjan求橋 割頂

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