go to the problem
割點:在乙個無向圖中,如果有乙個頂點集合,刪除這個頂點集合以及這個集合中所有頂點相關聯的邊以後,圖的連通分量增多,就稱這個點集為割點集合。割點如果某個割點集合只含有乙個頂點x(也即是乙個割點集合),那麼x稱為乙個割點。
給出乙個n個點,m條邊的無向圖,求圖的割點。
輸入格式:
第一行輸入n,m
下面m行每行輸入x,y表示x到y有一條邊
輸出格式:
第一行輸出割點個數
第二行按照節點編號從小到大輸出節點,用空格隔開
輸入樣例#1:
6 71 21 3
1 42 5
3 54 5
5 6
輸出樣例#1:
15
n,m均為100000
tarjan 圖不一定聯通!!!
注意與tarjan 求強連通分量的方法區別。
求割點不需要用到棧。
1 #include2 #include3 #include4 #include5 #include6using
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的所有子節點...