1. 程式人生 > >【模板】割點

【模板】割點

pac 最小 縮點 模板 esp .org ring 頂點 roo

【模板】割點

割點集合:一個頂點集合V,刪除該集合的所有定點以及與這些頂點相連的邊後,原圖不連通,就稱集合V為割點集合

點連通度:最小割點集合中的頂點數

邊連通度:最小割邊集合中的邊數

割點:割點集合中唯一的一個元素

Tarjan求縮點:

一個點為縮點的條件:

1.該點為根,搜索樹中有大於1個子樹

2.該點u不為根,存在兒子v,dfn[u]>low[v]

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define
N 100010 6 #define M 200010 7 int n,m,dfn[N],low[N]; 8 int head[N],num,root,cnt; 9 bool gd[N]; 10 inline int read(){ 11 int x=0; char c=getchar(); 12 while(c<0||c>9) c=getchar(); 13 while(0<=c&&c<=9) { x=(x<<3)+(x<<1)+c-0; c=getchar(); } 14 return x;
15 } 16 struct NODE{ 17 int to,next; 18 } e[M]; 19 inline void add(int x,int y){ 20 e[++num].to=y; 21 e[num].next=head[x]; 22 head[x]=num; 23 } 24 void Tarjan(int u){ 25 dfn[u]=low[u]=++cnt; 26 int tot=0; 27 for(int i=head[u];i;i=e[i].next) 28 if(!dfn[e[i].to]){ 29 tot++;
30 Tarjan(e[i].to); 31 low[u]=min(low[u],low[e[i].to]); 32 if((u==root&&tot>1)||(u!=root&&dfn[u]<=low[e[i].to])) 33 gd[u]=1; 34 } 35 else 36 low[u]=min(low[u],dfn[e[i].to]); 37 } 38 int main() 39 { 40 scanf("%d%d",&n,&m); 41 int x,y; 42 for(int i=1;i<=m;i++){ 43 x=read(); y=read(); 44 add(x,y); add(y,x); 45 } 46 for(int i=1;i<=n;i++) 47 if(!dfn[i]){ 48 root=i; Tarjan(i); 49 } 50 int ans=0; 51 for(int i=1;i<=n;i++) 52 if(gd[i]) ans++; 53 printf("%d\n",ans); 54 for(int i=1;i<=n;i++) 55 if(gd[i]) 56 printf("%d ",i); 57 return 0; 58 }

【模板】割點