tarjan算法

补一年前的坑。

有向图强连通分量

inline void tarjan(int x){
    dfn[x]=low[x]=++dt,sta[++tp]=x,ins[x]=1;
    forg(i,x)
        if(!dfn[to[i]])tarjan(to[i]),low[x]=min(low[x],low[to[i]]);
        else if(ins[to[i]])low[x]=min(low[x],dfn[to[i]]);
    if(dfn[x]==low[x]){
        ++bn;int y;
        do y=sta[tp--],ins[y]=0,bel[y]=bn;
        while(x!=y);
    }
}

low数组啥意思我也说不清,大概理解成一个辅助数组吧。。这个算法的妙处就在于,一个强联通分量的所有点,都会在标号最小的那个点那里被统计到。

无向图边双

inline void tarjan(int x,int e){
    dfn[x]=low[x]=++dt;
    forg(i,x)if(!dfn[to[i]]){
        tarjan(to[i],i),low[x]=min(low[x],low[to[i]]);
        if(low[to[i]]>dfn[x])br[i]=br[i^1]=1;
    }else if(i!=(e^1))low[x]=min(low[x],low[to[i]]);
}

无向图点双

inline void tarjan(int x){
    dfn[x]=low[x]=++dt;
    int c=0;
    forg(i,x)if(!dfn[to[i]]){
        tarjan(to[i]);low[x]=min(low[x],low[to[i]]);
        if(low[to[i]]>=dfn[x]){
            ++c;if(x!=rt||c>1)cut[x]=1;
        }
    }else low[x]=min(low[x],dfn[to[i]]);
}

比有向图简单多了。

原文地址:https://www.cnblogs.com/happyguy/p/14614382.html