这是初稿代码(0pts)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<map>
using namespace std;
const int N=2e4+4;
const int M=1e5+5;
int n,m,tot=1,h[N],cnt,f[N],son[N],root;
int awa,low[N],dfn[N];
stack<int> st;
struct sw{
int u,v,nxt;
}e[2*M];
void add(int u,int v){
tot++;
e[tot].u=u;
e[tot].v=v;
e[tot].nxt=h[u];
h[u]=tot;
}
void tar(int u,int fa){
dfn[u]=low[u]=++awa;
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;
if(!dfn[v]){
son[u]++;
//cout<<u<<"->"<<v<<endl;
//cout<<"son["<<u<<"]="<<son[u]<<endl;
tar(v,u);
low[u]=min(low[u],low[v]);
}
else if(v!=fa){
low[u]=min(low[u],dfn[v]);
}
if(low[v]>=dfn[u]&&u!=root){
f[u]=1;cnt++;
}
}
if(u==root&&son[root]>1&&!f[root]){
//cout<<"root:"<<son[root]<<endl;
f[root]=1;cnt++;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++){
if(dfn[i]) continue;
root=i;
tar(i,0);
}
//if(de[1]>=2){
// cnt++;
//}
printf("%d\n",cnt);
//if(de[1]>=2){
// printf("1\n");
//}
for(int i=1;i<=n;i++){
if(f[i]) printf("%d ",i);
}
return 0;
}
第二稿将判断非根割点的代码从扔到循环最后
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;
if(!dfn[v]){
son[u]++;
tar(v,u);
low[u]=min(low[u],low[v]);
}
else if(v!=fa){
low[u]=min(low[u],dfn[v]);
}
if(low[v]>=dfn[u]&&u!=root){
f[u]=1;cnt++;
}
}
改成tarjan子节点之后就过了
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;
if(!dfn[v]){
son[u]++;
tar(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=root&&!f[u]){
f[u]=1;cnt++;
}
}
else if(v!=fa){
low[u]=min(low[u],dfn[v]);
}
}
请问这是为什么
求dalao解答