zoukankan      html  css  js  c++  java
  • 【图论】割点和桥

    struct CutvertexBridge {
    
        static const int MAXN = 2e5 + 10;
        static const int MAXM = 2e6 + 10;
    
        int n, m, t;
    
        struct Edge {
            int v, nxt;
        } e[MAXM * 2];
        int h[MAXN];
    
        int dfn[MAXN], low[MAXN];
        bool cut[MAXN], brg[MAXM];
    
        void Init(int n) {
            this->n = n, m = 1;
            for(int i = 1; i <= n; ++i)
                h[i] = 0;
        }
    
        void AddEdge(int u, int v) {
            if(u == v) {
                m += 2;
                return;
            }
            e[++m] = {v, h[u]}, h[u] = m;
            e[++m] = {u, h[v]}, h[v] = m;
        }
    
        void dfs1(int u, int root) {
            dfn[u] = low[u] = ++t;
            for(int i = h[u], cnt = 0; i; i = e[i].nxt) {
                int v = e[i].v;
                if(!dfn[v]) {
                    dfs1(v, root);
                    low[u] = min(low[u], low[v]);
                    if(low[v] >= dfn[u]) {
                        if(u != root || ++cnt > 1)
                            cut[u] = 1;
                    }
                } else
                    low[u] = min(low[u], dfn[v]);
            }
        }
    
        void dfs2(int u, int from) {
            dfn[u] = low[u] = ++t;
            for(int i = h[u]; i; i = e[i].nxt) {
                int v = e[i].v;
                if(!dfn[v]) {
                    dfs2(v, i ^ 1);
                    low[u] = min(low[u], low[v]);
                    if(low[v] > dfn[u])
                        brg[i / 2] = 1;
                } else if(i != from)
                    low[u] = min(low[u], dfn[v]);
            }
        }
    
        void GetCutvertexs() {
            t = 0;
            for(int i = 1; i <= n; ++i)
                dfn[i] = low[i] = cut[i] = 0;
            for(int i = 1; i <= n; ++i) {
                if(!dfn[i])
                    dfs1(i, i);
            }
        }
    
        void GetBridges() {
            t = 0;
            for(int i = 1; i <= n; ++i)
                dfn[i] = low[i] = 0;
            for(int i = 2; i <= m; i += 2)
                brg[i / 2] = 0;
            for(int i = 1; i <= n; ++i) {
                if(!dfn[i])
                    dfs2(i, 0);
            }
        }
    
    } cb;
    

    验证链接:[洛谷P3388 割点] | [HDU4738 Caocao's Bridges]

    割点和桥都和dfs搜索树非常相关,可以根据搜索树的树形dp做文章(统计子树大小之类),这个时候桥可能应该用点v表示(易知若(u,v)是桥,那么v到其搜索树的父节点u的边唯一)。

    不存在割点的无向连通图叫“点双连通图”,不存在桥的无向连通图叫“边双连通图”

  • 相关阅读:
    休息一会。。。。。。
    iPhone开发之webview 拖动和显示本地图片的几组代码
    Android 防止手机休眠
    Android数据存储SQLite 事务操作
    解决png图片在IE6下的透明问题
    教你如何在博客园放“可运行"代码
    弹出层原理
    右键集成JS文件压缩 YUI Compressor
    原来window.event快达到全浏览器支持了
    QWrap入门指南
  • 原文地址:https://www.cnblogs.com/purinliang/p/14322233.html
Copyright © 2011-2022 走看看