Tarjan注意事项

割点判断 $low_v \ge dfn_u$
割桥 $low_v > dfn_u$
缩点/强连通分量,更新要判断点是否在栈中
点双,多看看。
求出所有的桥以后,把桥边删除,原图变成了多个连通块,则每个连通块就是一个边双连通分量。先用 Tarjan 算法标记处所有的桥边,再对整个无向图 DFS 一遍(遍历的过程中不访问桥边),划分出每个连通块。

割点

void tarjan(int u, int f)
{
    dfn[u] = low[u] = ++tim;
    int child = 0;
    FR
    {
        if (!dfn[v])
        {
            child++;
            tarjan(v, u);
            low[u] = min(low[u], low[v]);
            if (u != f && low[v] >= dfn[u])
                IsDi[u] = 1;
            if (u == f && child > 1)
                IsDi[u] = 1;
        }
        low[u] = min(low[u], dfn[v]);
    }
}

割桥

void tarjan(int u , int f) {
    dfn[u] = low[u] = ++tim;
    FR {
        if(v == f) continue;
        if(!dfn[v]) 
            {
                tarjan(v , u);
                low[u] = min(low[u] , low[v]);
                if(low[v] > dfn[u]) ans[++tot] = mp(min(u , v) , max(u , v));
            }
        low[u] = min(low[u], dfn[v]);
    }
}

缩点

void tarjan(int u)
{
    dfn[u] = low[u] = ++tim;
    st[++top] = u, ins[u] = 1;
    FR  
    { 
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else  if(ins[v])
            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u])
    {
        ++cot;
        int y;
        do
        {
            y = st[top--], ins[y] = 0;
            c[y] = cot, scc[cot].push_back(y);
            dga[cot] += val[y];
        } while (u != y);
    }
}

点双联通分量

void tarjan(int u, int f) {
    int cnt = 0;
    dfn[u] = low[u] = ++tim;
    st[++top] = u;
    for(int i = head[u]; i; i = e[i].next) {
        int v = e[i].to;
        if(v == f) continue;
        if(!dfn[v]) {
            cnt++;
            tarjan(v, u);
            low[u] = min(low[v], low[u]);
            if(low[v] >= dfn[u]) {
                int t;
                ++tot;
                while(st[top + 1] != v) DSS[tot].push_back(st[top--]);
                DSS[tot].push_back(u);
            } 
        } else low[u] = min(low[u], dfn[v]);
    }
    if(!f && !cnt) DSS[++tot].push_back(u), top--;
}
posted @ 2023-02-23 19:42  Saka_Noa  阅读(9)  评论(0)    收藏  举报  来源