洛谷3388-割点-C++ && python-(tarjan割点算法)
AC代码
C++
#include<iostream>
#include<vector>
using namespace std;
#define N 20010
int n,m;
int dfn[N],low[N],vis[N],tim=1;
int flag[N],u,v;
vector<int> point[N];
int min(int x,int y){
return x>y?y:x;
}
void tarjan(int cur,int far){
dfn[cur]=tim;
low[cur]=tim++;
int child=0;
for(int i=0;i<point[cur].size();i++){
int v=point[cur][i];
if(!vis[v]){
vis[v]=1;
child++;
tarjan(v,cur);
low[cur]=min(low[cur],low[v]);
if(cur!=far && low[v]>=dfn[cur])
flag[cur]=1;
if(cur==far and child>=2)
flag[cur]=1;
}
else if(v!=far){
low[cur]=min(low[cur],dfn[v]);
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
point[u].push_back(v);
point[v].push_back(u);
}
for(int i=1;i<=n;i++){
if(dfn[i]==0){
vis[i]=1;
tarjan(i,i);
}
}
int tmp=0;
for(int i=1;i<=n;i++){
if(flag[i])
tmp++;
}
printf("%d
",tmp);
for(int i=1;i<=n;i++){
if(flag[i])
printf("%d ",i);
}
return 0;
}
Python
global n,m
global point
global dfn,low,vis,time
global flag
global root
def tarjan(cur,far):
global time
dfn[cur],low[cur]=time,time
time+=1
child=0
for i in range(len(point[cur])):
v=point[cur][i]
if not vis[v]:
vis[v]=1
child+=1
tarjan(v,cur)
low[cur]=min(low[cur],low[v])
if cur!=far and low[v]>=dfn[cur]:
flag[cur]=1
if cur==far and child>=2:
flag[cur]=1
elif v!=far:
low[cur]=min(low[cur],dfn[v])
n,m=map(int,input().split())
point=[[] for _ in range(n+1)]
for i in range(m):
x,y=map(int,input().split())
point[x].append(y)
point[y].append(x)
dfn=[0 for _ in range(n+1)]
low=[0 for _ in range(n+1)]
vis=[0 for _ in range(n+1)]
flag=[0 for _ in range(n+1)]
time=1
for i in range(1,n+1):
if dfn[i]==0:
vis[i]=1
tarjan(i,i)
print(sum(flag))
for i in range(1,n+1):
if flag[i]:
print(i,end=" ")
