割点集合:一个顶点集合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 ",ans); 54 for(int i=1;i<=n;i++) 55 if(gd[i]) 56 printf("%d ",i); 57 return 0; 58 }