ZJU 3362 Beer Problem
赤裸裸的最小费用流
代码
/*
* File: ZJU 3362 Beer Problem
* Author: xiaotian @ hnu
* Created on 2010年10月30日, 下午12:05
* 解题:
*/
#include<iostream>
#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
const int N = 105;
const int E = 8100;
const int inf = 0x7ffffff;
int mincost, maxflow;
int n, m;
int U[E], V[E], cap[E], flow[E], cost[E], next[E];
int head[N], pre[N], Edge[N], dis[N];
int e;
void addEdge(int u, int v, int Cap, int Cost)
{
flow[e] = flow[e + 1] = 0;
V[e] = v; U[e] = u; cap[e] = Cap; cost[e] = Cost;
next[e] = head[u]; head[u] = e++;
V[e] = u; U[e] = v; cap[e] = 0; cost[e] = -Cost;
next[e] = head[v]; head[v] = e++;
}
void MCMF(int st, int ed) {
queue<int> q;
memset(flow, 0, sizeof (flow));
mincost = maxflow = 0;
for (;;) {
bool inq[N];
for (int i = st; i <= ed; ++i)
dis[i] = (i == st ? 0 : inf);
memset(inq, 0, sizeof (inq));
q.push(st);
while (!q.empty()) {
int u = q.front();
q.pop();
inq[u] = 0;
for (int e = head[u]; e != -1; e = next[e]) {
if (cap[e] > flow[e] && dis[u] + cost[e] < dis[V[e]]) {
dis[V[e]] = dis[u] + cost[e];
pre[V[e]] = U[e];
Edge[V[e]] = e;
if (!inq[V[e]]) {
q.push(V[e]);
inq[V[e]] = 1;
}
}
}
}
if (dis[ed] >= 0) break;
int delta = inf;
for (int u = ed; u != st; u = pre[u])
delta = min(delta, cap[Edge[u]] - flow[Edge[u]]);
for (int u = ed; u != st; u = pre[u]) {
flow[Edge[u]] += delta;
flow[Edge[u] ^ 1] -= delta;
}
mincost += dis[ed] * delta;
maxflow += delta;
}
}
void build() {
int u, v, Cap, Cost;
e = 0;
memset(head, -1, sizeof (head));
for (int i = 2; i <= n; ++i) {
scanf("%d", &Cost);
addEdge(i, n + 1, inf, -Cost);
}
while (m--) {
scanf("%d%d%d%d", &u, &v, &Cap, &Cost);
addEdge(u, v, Cap, Cost);
addEdge(v, u, Cap, Cost);
}
}
int main() {
freopen("newfile", "r", stdin);
while (scanf("%d%d", &n, &m) != EOF) {
build();
MCMF(1, n + 1);
printf("%d\n", -mincost);
}
return 0;
}


浙公网安备 33010602011771号