zoukankan      html  css  js  c++  java
  • 无向图 割点模板 (转载)

    1.定义:

    割点:某个点是割点当且仅当删除该点和与该点相关联的边后图变得不连通。

    桥(割边):某条边是割边当且仅当删除该边后图变的不连通。

    双连通分支:图G的所有子图G'中,如果G'是连通的,则称G'是双连通子图。如果G'不是任何一个连通子图的真子图,那么图G'是双连通分支。特别的,点双连通分支又叫做块。

    2.求割点,桥

    对原图进行深度优先搜索,会生成一颗深度优先搜索生成树。定义dfs[u]为u在深度优先搜索生成树中被遍历到的序号,low[u]为u或者他的子树中可以通过非父子边追溯到的最早结点。

    那么一个顶点是割点,满足下列条件之一:

    1).u是树根,u有两个或两个以上的分支;

    2).u不是树根,(u,v)是树边且low[v]>=dfn[u]。

    边(u,v)是桥,当且仅当low[v]>dfn[u],(u,v)是树边。

    下面是自己总结了多人的模板后写的,自已的模板(我的风格的)

    性质:low[]的值相等的点为同一个连通分量。

    int root, cnt,son;

    //  root记录根下标,son为根直接连接的儿子的数量,当其>1时根为割点。
    int vis[Max], dfn[Max], low[Max];  

    //  dfn[i]为第i个结点在搜索树中的深度,low[u]定义为u或者u的子树中能够通过非父子边追溯到的最早的节点的DFS开始时间 如下图:红色为low的值,蓝色为dfn的值

    无向图 <wbr>割点模板




    bool cut[Max];

    // cut[i] = true说明第i个节点为割点。

    模板1:
    int dep[M],low[M],head[M];
    bool cut[M];
    int e,n,root,son;
    struct E
    {
        int to,nxt;
    }edge[M*M];
    
    void addedge (int cu,int cv)
    {
        edge[e].to = cv;
        edge[e].nxt = head[cu];
        head[cu] = e ++;
    }
    
    
    void dfs (int dep,int u)
    {
        dfn[u] = low[u] = dep;
        for (int i = head[u];i != -1;i = edge[i].nxt)
        {
            int v = edge[i].to;
            if (!dfn[v])
            {
                dfs (dep + 1,v);
                if (u == root)
                    son ++;
                else
                {
                    low[u] = min (low[u],low[v]);
                    if (dfn[u] <= low[v])        //.u不是树根,(u,v)是树边且low[v]>=dfs[u] 则为割点
                        cut[u] = true;
                }
            }
            else
                low[u] = min (low[u],dfn[v]);
        }
    }
    int main ()
    {
             .....
             .....
            root = 1,son = 0;
            dfs (1,root);
            int ans = 0;
            if (son > 1)
                ans ++;
            for (int i = 1;i <= n;i ++)
                if (cut[i])
                    ans ++;
          .......
    }
    
    模板2:
    
    
    int dfn[M],low[M],head[M],vis[M];
    bool cut[M];
    int e,n,cnt,root;
    struct E
    {
        int to,nxt;
    }edge[M*M];
    
    void addedge (int cu,int cv)
    {
        edge[e].to = cv;
        edge[e].nxt = head[cu];
        head[cu] = e ++;
    }
    
    void dfs (int u,int father,int dep)
    {
        int son = 0;
        vis[u] = 1;
        dfn[u] = low[u] = dep;
        for (int i = head[u];i != -1;i = edge[i].nxt)
        {
            int v = edge[i].to;
            if (vis[v] == 1&&v != father)
                low[u] = min (low[u],dfn[v]);
            if (vis[v] == 0)
            {
                dfs (v,u,dep + 1);
                son ++;
                low[u] = min (low[u],low[v]);
                if ((u == root && son > 1)||(u != root&&dfn[u] <= low[v]))
                    cut[u] = true;
                //if (dfn(u) < low(v))
                //    bridge[k][0] = u;
                 //   bridge[k++][1] = v;              // (u,v) 为桥
            }
        }
        vis[u] = 2;
    }
    int main ()
    {
           .......
            root = 1;
            dfs (root,-1,1);
            int ans = 0;
            for (int i = 1;i <= n;i ++)
                if (cut[i])
                    ans ++;
        ......
        ......
    }

     

  • 相关阅读:
    Ionic Tabs
    Ionic实战九:ionic视频播放
    Ionic实战八:ionic登陆页面源码
    Ionic实战七:Ionic 音乐以及社交页面
    Ionic实战六:日期选择控件
    Ionic实战五:ionic图表源码基于highcharts
    Ionic实战四:ionic 即时通讯_ionic仿雅虎邮箱
    Ionic实战三:Ionic 图片预览可放大缩小左右滑动demo-iClub图片预览
    Ionic实战二:购物车
    编译错误总汇
  • 原文地址:https://www.cnblogs.com/jackge/p/3053720.html
Copyright © 2011-2022 走看看