Tarjan求强连通分量+缩点板子

适用于有向图
一个图的一个强连通分量必定是它的搜索树的一个子树
当dfn[u]=low[u]时,表示u点是该强连通分量的根节点

主要在DFS的过程中维护一个栈,存储节点。

int n,m;
vector<int>e[maxn];
vector<int>Scc[maxn];
int dfn[maxn],low[maxn];
int tot;
int scc[maxn];
int P;
int instk[maxn];
int sz[maxn];
stack<int>stk;
void dfs(int u,int fa){
    low[u]=dfn[u]=++tot;
    stk.push(u);
    instk[u]=1;

    for(int v:e[u]){
        if(!dfn[v]){//树边
            dfs(v,u);
            low[u] =min(low[u],low[v]);
        }else if(instk[v]){//非树边
            low[u] = min(low[u],dfn[v]);
        }
    }

    if(dfn[u]==low[u]){
        ++P;
        //处理非根节点
        while(stk.top()!=u){
            Scc[P].pb(stk.top());
            scc[stk.top()]=P;
            sz[P]++;
            instk[stk.top()]=0;
            stk.pop();
        }
        //处理根节点
        Scc[P].pb(stk.top());
        scc[stk.top()]=P;
        sz[P]++;
        instk[stk.top()]=0;
        stk.pop();
    }
}
for(int i=1;i<=n;i++){
  if(!scc[i])dfs(i,0);
}

缩点:将一个有向图划分为若干个强连通分量,然后将强连通分量缩成若干个点,使新图转化为DAG图
它的模板就是求强连通分量的模板,只需要再处理原图的连边即可

posted @ 2025-09-02 14:24  Marinaco  阅读(10)  评论(0)    收藏  举报
//雪花飘落效果