emmm 小呆也要开始写模板了,因为懒被大佬们拉下了好多。。。
题目描述
给出一个n个点,m条边的无向图,求图的割点。
code:
#include <iostream>
#include <cstdio>
using namespace std;
const int wx=800017;
inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
}
int a[wx],ans,num,x,y,n,m,tot;
int dfn[wx],low[wx],head[wx],ok[wx];
struct e{
int nxt,to;
}edge[wx*2];
void add(int from,int to){
edge[++num].nxt=head[from];
edge[num].to=to;
head[from]=num;
}
void Tarjan(int u,int fa){
dfn[u]=low[u]=++tot; int child=0;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa)continue;
if(!dfn[v]){
Tarjan(v,u);
child++;
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])ok[u]=1;//当前点不是根节点
//并且v的返祖边也不能返到u以前的点
}
else if(dfn[v]<dfn[u]&&v!=fa){
low[u]=min(low[u],dfn[v]);//v在u之前出现.
}
}
if(child<=1&&!fa)ok[u]=0;
}
int main(){
n=read(); m=read();
for(int i=1;i<=m;i++){
int x,y;
x=read(); y=read();
add(x,y); add(y,x);
}
for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i,0);
for(int i=1;i<=n;i++)if(ok[i])a[++ans]=i;
printf("%d
",ans);
for(int i=1;i<=ans;i++)printf("%d ",a[i]);
return 0;
}