【模板】最小费用最大流
一个费用流板子:
namespace GR { const int N = 405; const int M = 15005; const int INF = (int)1e9; int s, t, n, yun, flow, cost; int las[N], cur[N], dis[N], iq[N], vi[N]; int to[M << 1], pr[M << 1], ca[M << 1], co[M << 1]; void Init(int _s, int _t, int _n) { s = _s, t = _t, n = _n, yun = 1; fill(las, las + 1 + n, 0); } void Add(int a, int b, int c, int d) { to[++yun] = b, ca[yun] = c, co[yun] = d, pr[yun] = las[a], las[a] = yun; to[++yun] = a, ca[yun] = 0, co[yun] = -d, pr[yun] = las[b], las[b] = yun; } int Spfa() { static queue<int> Q; fill(dis, dis + 1 + n, INF); fill(iq, iq + 1 + n, 0); dis[s] = 0, Q.push(s), iq[s] = 1; for (int x; !Q.empty(); ) { x = Q.front(), iq[x] = 0, Q.pop(); for (int i = las[x]; i; i = pr[i]) { if (ca[i] > 0 && dis[to[i]] > dis[x] + co[i]) { dis[to[i]] = dis[x] + co[i]; if (!iq[to[i]]) iq[to[i]] = 1, Q.push(to[i]); } } } return dis[t] != INF; } int Dfs(int x, int fl) { if (x == t || fl == 0) return fl; int us = 0; vi[x] = 1; for (int i = cur[x]; i; i = pr[i]) { cur[x] = i; if (ca[i] > 0 && !vi[to[i]] && dis[to[i]] == dis[x] + co[i]) { int f = Dfs(to[i], min(fl - us, ca[i])); ca[i] -= f, ca[i ^ 1] += f, us += f, cost += co[i] * f; if (fl == us) break; } } return us; } int Flow() { flow = cost = 0; while (Spfa()) { memcpy(cur, las, sizeof(int) * (n + 2)); fill(vi, vi + 1 + n, 0); flow += Dfs(s, INF); } return flow; } }