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; }