【模板】割点

【模板】割点

割点集合:一个顶点集合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 }

猜你喜欢

转载自www.cnblogs.com/yjkhhh/p/9261562.html