Tarjan割点割边模板
用于无向图
先对每一个连通块建立搜索树
对于搜索树的根节点,判断它是否是割点的条件是:其子树数量大于等于2
对于搜索树的非根节点,判断它是否是割点的条件是:它的子树连通块可以通过非树边到达它的祖先节点,这一过程使用low数组的树形dp解决
vector<int>e[maxn];
int dfn[maxn],low[maxn];
int bj[maxn];
int tot;
void tarjan(int x,int fa){
dfn[x]=low[x]=++tot;
int son=0;
for(int v:e[x]){
if(!dfn[v]){
son++;
tarjan(v,x);
low[x]=min(low[x],low[v]);
if(fa&&low[v]>=dfn[x])bj[x]=1;
}else if(v!=fa){
low[x] =min(low[x],dfn[v]);
}
}
if(fa==0){
if(son>=2){
bj[x]=1;
}
}
}
...
rep(i,1,n){
if(!dfn[i]){
tarjan(i,0);
}
}
对于割边,跳过每个节点v到其搜索树的父亲节点u的树边统计,判断:如果low[v]>dfn[u],那么u<->v的树边为割边
void tarjan(int x,int fa){
dfn[x]=low[x]=++tot;
for(int v:e[x]){
if(v==fa)continue;
if(!dfn[v]){
tarjan(v,x);
low[x]=min(low[x],low[v]);
if(low[v]>dfn[x]){
edge.pb(mp(min(v,x),max(v,x)));
}
}else{
low[x]=min(low[x],dfn[v]);
}
}
}

浙公网安备 33010602011771号