這裡求的割點的意義僅僅指的是:去掉這個點後,不能使得原圖聯通的點。
當然可能還會有別的各種各樣的奇怪樹,圖中的不同含義的“割點”。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,u,v,now,cnt,ans;
int head[N],dfn[N],low[N];
bool cut[N];
struct edge{int next,to;}e[2*N];
inline void add(int u,int v)
{
cnt++;
e[cnt].next=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void tarjan(int u,int fa)
{
int son=0;
dfn[u]=low[u]=++now;
for (register int i=head[u]; i; i=e[i].next)
{
if (!dfn[e[i].to])
{
tarjan(e[i].to,fa);
low[u]=min(low[u],low[e[i].to]);
if (u!=fa && low[e[i].to]>=dfn[u]) cut[u]=true;
if (u==fa) son++;
}
else low[u]=min(low[u],dfn[e[i].to]);
}
if (son>=2 && u==fa) cut[u]=true;
}
int main(){
scanf("%d%d",&n,&m);
for (register int i=1; i<=m; ++i) scanf("%d%d",&u,&v),add(u,v),add(v,u);
for (register int i=1; i<=n; ++i) if (!dfn[i]) tarjan(i,i);
for (register int i=1; i<=n; ++i) if (cut[i]) ans++;
printf("%d\n",ans);
for (register int i=1; i<=n; ++i) if (cut[i]) printf("%d ",i);
return 0;
}