Tarjan求割点 || Luogu P3388 【模板】割点(割顶)

时间:2023-03-09 15:28:42
Tarjan求割点 || Luogu P3388 【模板】割点(割顶)

题面:P3388 【模板】割点(割顶)

题解:无

代码:

 #include<cstdio>
#include<iostream>
#include<cstring>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int maxn=,maxm=1e5;
int N,M,num_edge=,edge_head[maxn+],u,v,DFN[maxn+],LOW[maxn+];
int ix=,son,g[maxn+],ans=;
struct Edge{
int to,nx;
}edge[maxm*+];
inline void Add_edge(int from,int to){
edge[++num_edge].nx=edge_head[from];
edge[num_edge].to=to;
edge_head[from]=num_edge;
return;
}
void Tarjan(int x,int fa){
DFN[x]=LOW[x]=++ix;
for(int i=edge_head[x];i;i=edge[i].nx){
int y=edge[i].to;
if(fa!=y){
if(DFN[y]==){
if(fa==)son++;
Tarjan(y,x);
LOW[x]=min(LOW[x],LOW[y]);
if(fa!=&&DFN[x]<=LOW[y]&&g[x]==){
g[x]=;
ans++;
}
}
else LOW[x]=min(LOW[x],DFN[y]);
}
}
return;
}
int main(){
scanf("%d%d",&N,&M);
for(int i=;i<=M;i++){
scanf("%d%d",&u,&v);
Add_edge(u,v);
Add_edge(v,u);
}
for(int i=;i<=N;i++)
if(DFN[i]==){
son=;
Tarjan(i,);
if(son>&&g[i]==){
g[i]=;
ans++;
}
}
printf("%d\n",ans);
for(int i=;i<=N;i++)if(g[i])printf("%d ",i);
return ;
}

By:AlenaNuna