#C240219B. 割点和桥


#C240219B. 割点和桥

标签(Label)

  • tarjan
  • 模板

网址(Website)

$\qquad$ P3388 【模板】割点(割顶)

代码(Code)

#include<algorithm>
#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 20123
#define M 201234
using namespace std;
inline int input(){
	int x=0,f=1;char t=getchar();
	while(!isdigit(t)){if(t=='-')f=-1;t=getchar();}
	while(isdigit(t)){x=x*10+t-'0';t=getchar();}
	return x*f;
}

int n,m,ans;

int to[M],nxt[M],hd[N],tot;
void build(int x,int y){
	to[++tot]=y,nxt[tot]=hd[x],hd[x]=tot;
	to[++tot]=x,nxt[tot]=hd[y],hd[y]=tot;
}

int dfn[N],low[N],t;
bool cut[N],bri[M];
void tarjan(int x,int root){
	dfn[x]=low[x]=++t;
	int k=0;
	for(int e=hd[x];e;e=nxt[e]){
		int y=to[e];
		if(!dfn[y]){
			tarjan(y,root);
			low[x]=min(low[x],low[y]);
			if(dfn[x]<low[y])	bri[e]=true;
			if(dfn[x]<=low[y] && x!=root) cut[x]=true;
			if(x==root) k++;
		}
		else low[x]=min(low[x],dfn[y]);
	}
	if(k>=2 && x==root) cut[x]=true;
}

//洛谷P3388
signed main(){
	n=input(),m=input();
	for(int i=1;i<=m;i++){
		int x=input(),y=input();
		build(x,y);
	}
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
	for(int i=1;i<=n;i++) if(cut[i]) ans++;
	printf("%d\n",ans);
	for(int i=1;i<=n;i++) if(cut[i]) printf("%d ",i);
	return 0;
}

文章作者: WolfDeer
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WolfDeer !
  目录