zoukankan      html  css  js  c++  java
  • 【关节点+桥】关节点和桥模板 Tarjan

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 1e5, M = 1e5;
    struct Edge {
        int v, next, idx;
        Edge(){}
        Edge(int _v, int _next, int _idx):
            v(_v), next(_next), idx(_idx){}
    }e[M];
    int dfn[N], deep, head[N], tot;
    bool iscut[N], isbri[M];
    
    void __init__()
    {
        tot = deep = 0;
        memset(head, -1, sizeof(head));
        memset(dfn, 0, sizeof(dfn));
        memset(iscut, 0, sizeof(iscut));
        memset(isbri, 0, sizeof(isbri));
    }
    
    void add(int u, int v, int idx)
    {
        e[tot] = Edge(v, head[u], idx);
        head[u] = tot++;
    }
    //lowi:i及其子孙通过回边所能走到的最早的祖先的dfn值
    int dfs(int u, int fa)
    {
        int lowu = dfn[u] = ++deep;//打上时间戳,并初始化low值
        int son = 0;//儿子数为0
        for(int i = head[u]; ~i; i = e[i].next) {
            int v = e[i].v;
            if(!dfn[v]) {//下一个点指向儿子
                son++;
                int lowv = dfs(v, u);
                lowu = min(lowu, lowv);
                if(lowv >= dfn[u]) iscut[u] = 1;//没有回边,是关节点
                if(lowv > dfn[u]) isbri[e[i].idx] = true;
            }
            else if(dfn[v] < dfn[u] && v != fa)//指向爷爷,发现回边
                lowu = min(lowu, dfn[v]);//利用回边来更新low值
        }
        if(fa == -1 && son == 1) iscut[u] = 0;//仅仅有1个儿子的根结点不是割顶
        return lowu;
    }
    
    int main()
    {
        __init__();
        return 0;
    }

  • 相关阅读:
    省选模拟25
    有关树链剖分
    有关矩阵的一点讨论
    洛谷 P3390 【模板】矩阵快速幂
    HDU P2089
    有关动态规划(主要是数位DP)的一点讨论
    HDU P2222 Keywords Search
    普通平衡树Tyvj1728、luogu P3369 (treap)
    POJ P2104 K-th Number
    POJ 3311Hie with the Pie
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4197164.html
Copyright © 2011-2022 走看看