P3388 【模板】割点(割顶)

题意: 求割点

无向图,割点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
int n,m,x,y,ans;
struct edge{
int to,next;
}e[MAX*10];
int head[MAX],tot=0;
void addedge(int u,int v){
e[tot].to=v;
e[tot].next=head[u];
head[u]=tot++;
}
int low[MAX],dfn[MAX];
int ind;
bool instack[MAX],iscut[MAX];
int tarjan(int u,int fa){
int cnt=0,lowu,lowv;
lowu=dfn[u]=++ind;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
if(v==fa) continue;
if(!dfn[v]){
cnt ++;
lowv=tarjan(v,u);
lowu=min(lowu,lowv);
if(lowv>=dfn[u]){ // >=
iscut[u]=true;
}
}else if(dfn[v]<dfn[u]){
lowu=min(lowu,dfn[v]);
}
}
if(fa<0 && cnt==1)
iscut[u]=false;
low[u]=lowu;
return lowu;
}
void solve(){
mem(dfn,0);
ind=0;
fi(i,1,n+1)
if(!dfn[i])
tarjan(i,-1);
}
int main(){
freopen("in","r",stdin);
sf(n);sf(m);
mem(head,-1);
fi(i,0,m){
sf(x);sf(y);
addedge(x,y);
addedge(y,x);
}
solve();
fi(i,1,n+1)
if(iscut[i])
ans ++;
printf("%d\n",ans);
fi(i,1,n+1)
if(iscut[i])
printf("%d ",i);
return 0;
}