首页 > 其他 > 详细

tarjan

时间:2021-04-08 18:23:58      阅读:20      评论:0      收藏:0      [点我收藏+]

有向图

强连通分量

void tarjan(int u) {
    dfn[u] = low[u] = ++times;
    stk[++top] = u;instk[u] = 1;
    for (int i  = h[u]; i != -1; i = ne[i]) {
        int v = to[i];
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (instk[u]) low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        ++scc_cnt;
        while (1) {
            int v = stk[top--];
            Size[scc_cnt] ++;
            id[v] = scc_cnt;
            instk[v] = 0;
            if (v == u)break;
        }
    }
}

无向图

求割边(桥),求边双连通分量

void tarjan(int u, int from) {
    dfn[u] = low[u] = ++times;
    stk[++top] = u;
    bool flag = 1;
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int v = to[i];
        if ((i^1) == from && flag) {flag = 0;continue;}//重边
        if (!dfn[v]) {
            tarjan(v, i);
            low[u] = min(low[u], low[v]);
            if (low[v] > dfn[u]) {
                ans++;//i和i^1是桥。
            }
        } else
            low[u] = min(low[u], dfn[v]);
    }
    if (low[u] == dfn[u]) {
        e_dcc++;
        while (1) {
            id[stk[top]] = e_dcc;
            if (stk[top--] == u)break;
        }
    }
}

求割点(割顶),求点双连通分量

void tarjan(int u, int fa) {
    dfn[u] = low[u] = ++times;
    stk[++top] = u;
    int cnt = 0;
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int v = to[i];
        if (!dfn[v]) {
            tarjan(v, fa), ++cnt;
            low[u] = min(low[u], low[v]);
            if (low[v] >= dfn[u]) {
                if (u != fa)cut[u] = 1;
                else cut[u] |= (cnt > 1);
                ++dcc;
                while (1) {
                    bl[stk[top]].push_back(dcc);//可以bl[dcc].push_back(stk[top]);
                    //主要是看自己需要啥,就咋写
                    sz[dcc]++;
                    if (stk[top--] == v)break;//这里确实有点不好理解,就是说,他这团是把当前这一团外面那一团给算上的,下次补一下图咕咕咕。
                }
                bl[u].push_back(dcc);
                sz[dcc]++;
            }
        } else
            low[u] = min(low[u], dfn[v]);
    }
}

tarjan

原文:https://www.cnblogs.com/Xiao-yan/p/14633093.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!