• 割点和桥


    割点和桥
    割点:无向图中,如果删除某个点以及和它相邻的所有边之后,图中连通分量数增加,则称该点为割点

    桥:无向图中,如果删除某条边之后,图中连通分量数增加,则称该边为桥
    tarjan算法计算割点和桥
    割点:
    1.如果节点(u)不是根,则当存在一个以(u)为根的子树中的节点(v),有(low[v]>=dfn[u])时,说明去掉(u)之后会使得(v)(u)的祖先节点不连通,(u)为割点
    2.如果节点(u)是根,则当根有多于一棵子树时,根为割点

    const int maxn=100010;
    int dfn[maxn],low[maxn],cut[maxn],dfscnt;
    
    void tarjan(int u,int fa){
        int child=0;
        dfn[u]=low[u]=++dfscnt;
        for(int i=head[u];~i;i=nxt[i]){
            int v=to[i];
            if(!dfn[v]){
                child++;
                tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(fa!=-1 && low[v]>=dfn[u]) cut[u]=1;
                if(fa==-1 && child>=2) cut[u]=1;
            }
            else if(v!=fa){
                low[u]=min(low[u],dfn[v]);
            }
        }
    }
    

    模板题:hdu1269 迷宫城堡

    桥:
    1.对于节点(u),如果存在一个子节点(v),有(low[v]>dfn[u]),说明删除(u)(v)之间的边之后,(v)无法和(u)及其的祖先节点连通,所以(u)(v)之间的边为桥
    2.重边一定不是桥,判断一条边是否为桥的时候需要判断是否有重边

    const int maxn=1010,maxm=2000010;
    int dfn[maxn],low[maxn],dfscnt,ans;
    int edge_cnt[maxn][maxn];
    vector<PII> bridge;
    
    void tarjan(int u,int fa){
        dfn[u]=low[u]=++dfscnt;
        for(int i=head[u];~i;i=nxt[i]){
            int v=to[i],w=weight[i];
            if(!dfn[v]){
                tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>dfn[u] && edge_cnt[u][v]==1) bridge.push_back({u,v});
            }
            else if(v!=fa){
                low[u]=min(low[u],dfn[v]);
            }
        }
    }
    

    模板题:hdu4738 Caocao's Bridges
    割点和桥的关系
    1.有割点不一定存在桥,有桥一定存在割点
    2.桥一定是连接割点的边

  • 相关阅读:
    python
    python中xrange和range的区别
    python
    shell用if
    shell调用shell
    An unhandled exception of type 'System.TypeInitializationException' occurred in System.ServiceModel.dll
    C# 获取存在DataTable1不存在DataTable2的数据的快速方法
    textbox自动提示
    全面理解面向对象的 JavaScript(转载)
    C#中文乱码转换
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13592535.html
Copyright © 2020-2023  润新知