zoukankan      html  css  js  c++  java
  • 割点和桥

    标题1

    一、定义

      连通度(百度百科):

        割点集合:无向图中,删除集合中所有的点以及点所连接的边后,无向图不连通的集合

        割边集合:无向图中,删除集合中所有的边后,无向图不连通的集合

        点连通度:无向图中,割点集合中最小集合中的元素个数

        边连通度:无向图中,割边集合中的最小集合的元素个数

      双联通图,割点,和桥:

        双联通图:无向图中,边连通度或者点连通度大于1

        桥:图的边连通度为1,割边集合中的唯一元素集合中的元素为桥

        割点:图的点连通度为1,割点集合中的唯一元素集合中的元素为桥

      双联通分量

        在图G所有子图中,如果G'是双联通子图,G'不是任何一个双连通子图的真子集,则G'是一个极大双联通子图,特殊的点双联通分量又叫做

      

    二、Tagan

      割点的条件:

        (满足一个即可)

        1.如果u树根,那么如果u的子树超过1,则u为割点

        2.如果u不为树根,且满足存在(u,v)为树枝边(u为v在搜索树中的父亲),并使得DFN(u)<=low(v)(删去u以及v以及v的子树不能到达u的祖先)

       

    #include<stdio.h>
    #include<stdlib.h>
    #define FORa(i,s,e) for(int i=s;i<=e;i++)
    #define FORs(i,s,e) for(int i=s;i>=e;i--)
    
    using namespace std;
    
    const int N=100,M=200;
    int n,m,num_edge,head[N+1],dfn[N+1],low[N+1],index;
    bool cut[N+1];
    struct Edge{
        int next,to;
    }edge[2*M+2]; 
    inline void Add_edge(int from,int to){
        edge[++num_edge]=(Edge){head[from],to},head[from]=num_edge;
    }
    inline int min(int fa,int fb){return fa<fb?fa:fb;}
    void Tarjan(int x)
    {
        low[x]=dfn[x]=++index;
        int cnt=0;
        for(int i=head[x];i;i=edge[i].next)
        {
            if(!dfn[edge[i].to])
            {
                cnt++;
                Tarjan(edge[i].to),low[x]=min(low[x],low[edge[i].to]);
                if(cnt>1&&x==1||dfn[x]<=low[edge[i].to])    cut[x]=1;
            }    
            else low[x]=min(low[x],dfn[edge[i].to]);
        }
    }
    int main()
    {
        int from,to;
        scanf("%d%d",&n,&m);
        FORa(i,1,m)
        {
            scanf("%d%d",&from,&to);
            Add_edge(from,to),Add_edge(to,from);
        }
        Tarjan(1);
        FORa(i,1,n) printf("%d ",cut[i]);
        return 0;
    }
    /*7 8
    1 5 
    1 4
    4 5
    1 2
    1 3
    4 3
    3 7
    3 6*/

      桥的条件:

        (满足一个即可)

        1.如果u树根,那么如果u的子树超过1,则u为割点

        2.如果u不为树根,且满足存在(u,v)为树枝边(u为v在搜索树中的父亲),并使得DFN(u)<=low(v)(删去u以及v以及v的子树不能到达u的祖先)

    #include<stdio.h>
    #include<stdlib.h>
    #define FORa(i,s,e) for(int i=s;i<=e;i++)
    #define FORs(i,s,e) for(int i=s;i>=e;i--)
    
    using namespace std;
    const int N=1000,M=2000;
    int n,m,num_edge=1,top,index,head[N+1],dfn[N+1],low[N+1],fa[N+1];
    //注意num_edge是从奇数开始的,因为只有从奇数开始,第一个数就是偶数,那么偶数^1就是比它大1的奇数了 
    bool bridge[M+1];
    struct Edge{
        int next,to;
    }edge[M+1];
    inline void Add_edge(int from,int to)
    {
        edge[++num_edge]=(Edge){head[from],to},head[from]=num_edge;
    }
    inline int min(int fa,int fb){return fa<fb?fa:fb;}
    inline void Tarjan(int u)
    {
        dfn[u]=low[u]=++index;
        for(int i=head[u],v;i;i=edge[i].next)
        {
            v=edge[i].to;
            if(i==(fa[u]^1)) continue;
            if(!dfn[v])
            {
                fa[v]=i,Tarjan(v);
                low[u]=min(low[u],low[v]);
                if(low[v]>dfn[u]) bridge[fa[v]]=bridge[fa[v]^1]=1;
            }
            else low[u]=min(low[u],dfn[v]);                                         
        }
    }
    int main()
    {
        int from,to;
        scanf("%d%d",&n,&m);
        FORa(i,1,m)
        {
            scanf("%d%d",&from,&to);
            Add_edge(from,to),Add_edge(to,from);
        }
        Tarjan(1);
        FORa(i,1,num_edge)
            if(bridge[i])
            {
                printf("%d",edge[i].to);
                printf(" %d
    ",edge[i+1].to);
            }
        return 0;
    }
    /*12
    16
    12 11
    11 8
    11 10
    8 10
    10 9
    9 8
    9 7
    7 6
    5 7
    6 5
    6 4
    6 3
    4 3
    2 3
    3 2
    4 1*/

    三、求双联通分量 

      点双联通分量:

         在求割点的时候,每一次找到树枝边和后向边,就将边加入到栈中,如果发现点u是割点,将栈中边(u,v)以上的边都弹出栈。这些边与边的点组成的图就是一个点强连通分量

      边双联同分量     

         在求桥的时候,求出桥(u,v)删去所有桥,剩下的连通块都是一个双联通分量,不包含桥

      将有桥的连通图变成双联通图:

         删去桥。将剩下的连通图缩成一个点,因为每一个连通图是一个边双联通分量,在边双联通图中加边不会减少桥的数目,所以先缩点

          我们可以看如果没有割边,根据树的性质,则将叶子结点连在一起就行,所以要连接的边数为(叶子结点+1)/2

        

  • 相关阅读:
    memcache概念浅谈及名称混乱之区分
    apache设置头
    Apache中关于页面缓存的设置
    memcahced&redis命令行cmd下的操作
    memcache命令行
    Memcached管理与监控
    memcache stats命令详解
    memcache基础知识-stats参数
    ab测试
    yum安装Apache,Mysql,PHP
  • 原文地址:https://www.cnblogs.com/SeanOcean/p/11262387.html
Copyright © 2011-2022 走看看