题目:hdu6118
裸的最小费用流模版,记录一下
代码如下:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 500 + 10;
const int maxm = 4000 + 10;
const int INF = (int)1e9;
int lst[maxn], nxt[2*maxm], to[2*maxm], c[2*maxm], f[2*maxm];
int in[maxn], dis[maxn];
int n, m, s, t, ans, cnt;
void add(int u, int v, int w, int fw) {
nxt[++cnt] = lst[u]; lst[u] = cnt; to[cnt] = v; c[cnt] = w; f[cnt] = fw;
nxt[++cnt] = lst[v]; lst[v] = cnt; to[cnt] = u; c[cnt] = -w; f[cnt] = 0;
}
queue<int> Q;
int pre[maxn];
bool spfa(){
for (int i = 1; i <= t; i ++) dis[i] = INF;
memset(pre, 0, sizeof(pre));
memset(in, 0, sizeof(in));
Q.push(s);
dis[s] = 0;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
in[u] = 0;
for (int j = lst[u]; j; j = nxt[j]) {
int v = to[j];
if (!f[j]) continue;
if (dis[u] + c[j] < dis[v]) {
dis[v] = dis[u] + c[j];
pre[v] = j;
if (!in[v]) {
in[v] = 1;
Q.push(v);
}
}
}
}
return dis[t] < 0;
}
void update(){
int now = t, fw = INF;
while (now != s) {
int kk = pre[now];
if (f[kk] < fw) fw = f[kk];
now = to[kk^1];
}
ans -= fw * dis[t];
now = t;
while (now != s) {
int kk = pre[now];
f[kk] -= fw;
f[kk^1] += fw;
now = to[kk^1];
}
}
int main(){
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
while (scanf("%d %d", &n, &m) == 2) {
memset(lst, 0, sizeof(lst)); cnt = 1;
memset(nxt, 0, sizeof(nxt));
s = n + 1; t = s + 1;
for (int i = 1; i <= n; i ++) {
int a, b, cc, d;
scanf("%d %d %d %d", &a, &b, &cc, &d);
add(s, i, a, b);
add(i, t, -cc, d);
}
for (int i = 1; i <= m; i ++) {
int a, b, w;
scanf("%d %d %d", &a, &b, &w);
add(a, b, w, INF);
add(b, a, w, INF);
}
ans = 0;
while (spfa()) update();
printf("%d\n", ans);
}
return 0;
}