洛谷P3388 【模板】割点(割顶)
题目背景
割点
题目描述
给出一个n个点,m条边的无向图,求图的割点。
输入输出格式
输入格式:
第一行输入n,m
下面m行每行输入x,y表示x到y有一条边
输出格式:
第一行输出割点个数
第二行按照节点编号从小到大输出节点,用空格隔开
输入输出样例
说明
n,m均为100000
tarjan 图不一定联通!!!
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 100010 using namespace std; int dfn[maxn],low[maxn],cnt,ans; bool cut[maxn]; int n,m,num,head[maxn]; struct node{ int from,to,pre; }e[maxn*2]; void Insert(int from,int to){ e[++num].to=to; e[num].from=from; e[num].pre=head[from]; head[from]=num; } void Tarjan(int u,int father){ int rc=0; cnt++;dfn[u]=low[u]=cnt; for(int i=head[u];i;i=e[i].pre){ int v=e[i].to; if(!dfn[v]){ Tarjan(v,father); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]&&u!=father)cut[u]=1; if(u==father)rc++; } low[u]=min(low[u],dfn[v]); } if(u==father&&rc>=2)cut[u]=1; } int main(){ freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&m); int x,y; for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); Insert(x,y);Insert(y,x); } 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); }