[模板] 割点

割点模板
为什么我一直没有写。。。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <ctime>
#include <set>
#include <map>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define go(i,k) for(int i=head[k],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
using namespace std;
typedef long long ll;
typedef double db;
const int inf=0x3f3f3f3f;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
	return x*f;
}
const int N=100005,M=1000005;
struct Edge{int to,nxt;}e[M];
int head[N],ecnt,dfn[N],low[N],tim,n,m;
bool cut[N];
inline void add(int bg,int ed) {e[++ecnt]=(Edge) {ed,head[bg]};head[bg]=ecnt;}
void tarjan(int x,int rt) {
	dfn[x]=low[x]=++tim;
	int f=0;
	go(i,x) {
		if(!dfn[v]) {
			tarjan(v,rt);
			low[x]=min(low[v],low[x]);
			if(low[v]>=dfn[x]&&x!=rt) cut[x]=1;
                        //如果当前点的子结点不能访问到之前访问过的点,那么这个点一定是割点
			if(x==rt) f++;
		}
		else low[x]=min(low[x],dfn[v]);
	}
	if(f>=2) {cut[rt]=1;}
}
int main() {
#ifdef HSZ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	n=rd(),m=rd();
	int a,b;
	fo(i,1,m) a=rd(),b=rd(),add(a,b),add(b,a);
	fo(i,1,n) if(!dfn[i])tarjan(i,i);
	int ans=0;
	fo(i,1,n) if(cut[i]) ans++;
	printf("%d\n",ans);
	fo(i,1,n) if(cut[i]) printf("%d ",i);
	return 0;
}
posted @ 2018-10-29 09:53  SWHsz  阅读(178)  评论(0编辑  收藏  举报