zoukankan      html  css  js  c++  java
  • BZOJ 3876 统一下界上下界费用流

    //Mcmf LargeDumpling
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int INF = 0x7f7f7f7f;
    const int MAXN = 505, MAXM = 13000;
    int need[MAXN], day, p, kd, kf, md, mf;
    int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], costflow[MAXM << 1], ed, S, T;
    int x[MAXN], y[MAXN], pre[MAXN];
    bool exist[MAXN];
    int needflow[MAXN], sumneed = 0, SS, TT;
    inline void addedge(int u, int v, int cap, int val)
    {
        to[++ed] = v;
        nxt[ed] = Head[u];
        Head[u] = ed;
        f[ed] = cap;
        costflow[ed] = val;
        to[++ed] = u;
        nxt[ed] = Head[v];
        Head[v] = ed;
        f[ed] = 0;
        costflow[ed] = -1 * val;
        return;
    }
    bool BFS()
    {
        int u;
        queue<int>q;
        memset(exist, false, sizeof(exist));
        memset(lev, 127, sizeof(lev));
        lev[S] = pre[S] = 0;
        q.push(S);
        while (q.size()) {
            u = q.front();
            q.pop();
            exist[u] = false;
            for (int i = Head[u]; i; i = nxt[i])
                if (f[i] && lev[u] + costflow[i] < lev[to[i]]) {
                    lev[to[i]] = lev[u] + costflow[i];
                    pre[to[i]] = i;
                    if (!exist[to[i]]) {
                        exist[to[i]] = true;
                        q.push(to[i]);
                    }
                }
        }
        memcpy(cur, Head, sizeof(Head));
        return lev[T] != INF;
    }
    int DFS(int u, int maxf)
    {
        if (u == T || !maxf) {
            return maxf;
        }
        exist[u] = true;
        int cnt = 0;
        for (int &i = cur[u], tem; i; i = nxt[i])
            if (f[i] && lev[u] + costflow[i] == lev[to[i]]) {
                if (exist[to[i]]) {
                    continue;
                }
                tem = DFS(to[i], min(f[i], maxf));
                maxf -= tem;
                f[i] -= tem;
                f[i ^ 1] += tem;
                cnt += tem;
                if (!maxf) {
                    break;
                }
            }
        if (!cnt) {
            lev[u] = -1 * INF;
        }
        exist[u] = false;
        return cnt;
    }
    int Augment()
    {
        int delta = INF;
        for (int i = pre[T]; i; i = pre[to[i ^ 1]])
            if (f[i] < delta) {
                delta = f[i];
            }
        for (int i = pre[T]; i; i = pre[to[i ^ 1]]) {
            f[i] -= delta;
            f[i ^ 1] += delta;
        }
        return delta * lev[T];
    }
    int MCMF()
    {
        int ans = 0;
        memset(exist, false, sizeof(exist));
        while (BFS())
            //ans+=DFS(S,INF)*lev[T];
        {
            ans += Augment();
        }
        return ans;
    }
    void init(int S1, int T1, int S2, int T2)
    {
        memset(Head, 0, sizeof(Head));
        ed = 1;
        S = S1;
        T = T1;
        SS = S2;
        TT = T2;
        return;
    }
    inline void Add(int u, int v, int lowcap, int topcap, int val)
    {
        addedge(u, v, topcap - lowcap, val);
        needflow[u] -= lowcap, needflow[v] += lowcap;
    }
    void pushdownflow(int n) //after init
    {
        for (int i = 1; i <= n; i++) {
            if (needflow[i] < 0) {
                addedge(i, TT, -needflow[i], 0);
            }
            if (needflow[i] > 0) {
                addedge(SS, i, needflow[i], 0);
                sumneed += needflow[i];
            }
        }
    }
    int main()
    {
        int n;
        scanf("%d", &n);
        init(n + 1, n + 2, n + 3, n + 4);
        int u, v, k, c;
        int sumcost = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &k);
            for (int j = 1; j <= k; j++) {
                scanf("%d %d", &v, &c);
                Add(i, v, 1, 0x3f3f3f3f, c);
                sumcost += c;
            }
        }
        pushdownflow(n);
        for (int i = 1; i <= n; i++) {
            addedge(i, 1, 0x3f3f3f3f, 0);
        }
        S = SS, T = TT;
        int ans = MCMF();
        printf("%d
    ", ans + sumcost);
        return 0;
    }
  • 相关阅读:
    【Redis】搭建主从复制
    【安装】Ubuntu之Docker
    【安装】Ubuntu之MySQL
    【Docker】Dockerfile构建指令
    【Docker】常用命令
    【14】Flask 请求上下文
    【13】Flask 上下文前夕
    【12】Flask 分析线程和协程
    【11】Flask 高级进阶
    【10】Flask 高级摘要
  • 原文地址:https://www.cnblogs.com/Aragaki/p/9767314.html
Copyright © 2011-2022 走看看