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

 

posted @ 2010-10-30 12:25  晓天  阅读(214)  评论(0)    收藏  举报