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\n", ans + sumcost);
    return 0;
}

 

posted @ 2018-10-10 16:32  Aragaki  阅读(165)  评论(0编辑  收藏  举报