• 【图论】二分图最大匹配


    验证链接:[洛谷P3386 - 二分图最大匹配]

    最大流

    int N = n1 + n2, S = ++N, T = ++N;
    dinic.Init(N, S, T);
    for(int i = 1; i <= n1; ++i) {
        int V1i = i;
        dinic.AddEdge(S, V1i, 1);
    }
    for(int i = 1; i <= n2; ++i) {
        int V2i = n1 + i;
        dinic.AddEdge(V2i, T, 1);
    }
    while(m--) {
        int u = ?, v = ?;
        int V1i = u, V2i = n1 + v;
        dinic.AddEdge(V1i, V2i, 1);
    }
    int ans = dinic.Maxflow();
    

    Dinic模板

    求解二分图等单位网络时,复杂度为 (O(msqrt{n}))
    除了超级点外,所有点的“入度和出度的最小值”不超过1的,为单位网络。

    struct Dinic {
    
        static const int MAXN = 2e5 + 10;
        static const int MAXM = 4e6 + 10;
    
        int n, m, s, t;
    
        struct Edge {
            int v, nxt;
            ll flow;
        } e[MAXM];
        int h[MAXN];
    
        int que[MAXN], dep[MAXN], cur[MAXN];
    
        bool BFS() {
            memset(dep, 0, sizeof(dep[0]) * (n + 1));
            memcpy(cur, h, sizeof(cur[0]) * (n + 1));
            int l = 1, r = 0;
            que[++r] = s, dep[s] = 1;
            while(l <= r) {
                int u = que[l++];
                for(int i = h[u]; i; i = e[i].nxt) {
                    if(e[i].flow && !dep[e[i].v])
                        dep[e[i].v] = dep[u] + 1, que[++r] = e[i].v;
                }
            }
            return dep[t];
        }
    
        ll DFS(int u, ll in) {
            if(u == t)
                return in;
            ll out = 0;
            for(int &i = cur[u]; i; i = e[i].nxt) {
                if(e[i].flow && dep[u] + 1 == dep[e[i].v]) {
                    ll res = DFS(e[i].v, min(in, e[i].flow));
                    e[i].flow -= res, in -= res;
                    e[i ^ 1].flow += res, out += res;
                    if(in == 0)
                        break;
                }
            }
            if(out == 0)
                dep[u] = 0;
            return out;
        }
    
        void Init(int n, int s, int t) {
            this->n = n, m = 1, this->s = s, this->t = t;
            for(int i = 1; i <= n; ++i)
                h[i] = 0;
        }
    
        void AddEdge(int u, int v, ll w) {
            e[++m] = {v, h[u], w}, h[u] = m;
            e[++m] = {u, h[v], 0}, h[v] = m;
        }
    
        ll Maxflow() {
            ll flow = 0;
            while(BFS())
                flow += DFS(s, LINF);
            return flow;
        }
    
    } dinic;
    
  • 相关阅读:
    ibatis插入正确但查询不出数据的问题
    Java 动态代理机制分析及扩展--转
    java实现插入排序算法 附单元测试源码
    unix基础知识
    作为大数据和云计算学习的一个序吧
    Understanding JVM Internals---不得不转载呀
    回文推理
    java 正则表达式提取html纯文本
    OpenCV功能界面和示例
    【POJ3268】Silver Cow Party 最短
  • 原文地址:https://www.cnblogs.com/purinliang/p/14318300.html
Copyright © 2020-2023  润新知