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]);
        }
    }
}
posted @ 2025-09-02 13:26  Marinaco  阅读(7)  评论(0)    收藏  举报
//雪花飘落效果