zoukankan      html  css  js  c++  java
  • 无向图的双连通分量

    双连通包括两种:  

      1、点-双连通: 任意两点之间至少存在两条“点不重复”的路径,即内部无割顶。

      2、边-双连通: 任意两点之间至少存在两条“边不重复的”路径,即内部无桥。

    如图:

    两个点-双连通分量:{1,2,3}、{3,4,5};

    一个边-双连通分量:{1,2,3,4,5};

    还是利用无向图的割顶和桥的数据结构,和思想。

    每次成功找到没有访问的点,边入栈,当发现 子节点v 不能连到 u 的 祖先,那么一个点 - 连通分量找到了。

    不断出栈,这些边都是点-连通分量的边。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int Maxnode = 1000;
    
    int pre[Maxnode<<1];
    
    bool iscut[Maxnode];
    int bccno[Maxnode];
    int dfs_clock;
    int bcc_cnt;
    
    vector<int> G[Maxnode],bcc[Maxnode];
    
    struct Edge
    {
        int u,v;
        Edge(int u=0,int v = 0) : u(u),v(v) {}
    };
    
    stack<Edge> S;
    
    int dfs(int u,int fa)
    {
        int lowu = pre[u] = ++dfs_clock;
        int child = 0;
    
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            Edge e = (Edge) { u,v };
            if(!pre[v])
            {
                S.push(e);
                child ++;
                int lowv = dfs(v,u);
                if(lowv>=pre[u])
                {
                    iscut[u] = true;
                    bcc_cnt ++;
                    bcc[bcc_cnt].clear();
    
                    for(;;)
                    {
                        Edge x = S.top();
                        S.pop();
                        if(bccno[x.u]!=bcc_cnt)
                        {
                            bcc[bcc_cnt].push_back(x.u);
                            bccno[x.u] = bcc_cnt;
                        }
                        if(bccno[x.v]!=bcc_cnt)
                        {
                            bcc[bcc_cnt].push_back(x.v);
                            bccno[x.v] = bcc_cnt;
                        }
                        if(x.u==u&&x.v==v) break;
                    }
                }
            }
            else if(pre[v]<pre[u]&&v!=fa)
            {
                S.push(e);
                lowu = min(lowu,pre[v]);
            }
        }
    
        if(fa<0&&child==1)
                iscut[u] = 0;
        return lowu;
    }
    
    void find_bcc(int n) {
    
        memset(pre,0,sizeof(pre));
        memset(iscut,0,sizeof(iscut));
        memset(bccno,0,sizeof(bccno));
    
        dfs_clock = bcc_cnt = 0;
    
        for(int i=0;i<n;i++) {
            if(!pre[i]) {
                dfs(i,-1);
            }
        }
    
    
    }
  • 相关阅读:
    小程序入门
    页面滚动触底加载
    js取整
    【Codeforces 1389D】Segment Intersections
    【Codeforces 1385 E】Directing Edges
    【Codeforces 1369D】TediousLee
    【Codeforces Global Round 9 D】Replace by MEX
    【Codeforces Global Round 9 C】Element Extermination
    【Codeforces Round #639 (Div. 2) A】Puzzle Pieces
    【Codeforces Round #639 (Div. 2) B】Card Constructions
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6067189.html
Copyright © 2011-2022 走看看