poj2516
/***************************************************************\ * Author: Hu Wenbiao * Created Time: Sat 02 Oct 2010 08:31:09 PM CST * File Name: main.cpp * Description: 最小费用最大流。对每种货物用一次mcmf。 \***************************************************************/ //*========================*Head File*========================*\\ #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<queue> /*----------------------*Global Variable*----------------------*/ #define maxn 105 #define inf 0x3f3f3f3f struct edge { int v, w, f, c, next; } e[5100]; int vst[maxn], dis[maxn], start[maxn], p[maxn]; int tot, N, M, K, flow_sum, ans, need[60][60], supply[60][60], cost, good_sum; //*=======================*Main Program*=======================*// using namespace std; void _add(int v, int w, int f, int c) { e[tot].v = v; e[tot].w = w; e[tot].f = f; e[tot].c = c; e[tot].next = start[v]; start[v] = tot++; } void add(int v, int w, int f, int c) { _add(v, w, f, c); _add(w, v, 0, -c); } bool spfa(int s, int t, int n) { int v, w; queue < int >q; for (int i = 0; i < n; i++) { p[i] = -1;; vst[i] = 0; dis[i] = inf; } vst[s] = 1; dis[s] = 0; q.push(s); while (!q.empty()) { v = q.front(); q.pop(); vst[v] = false; for (int i = start[v]; i != -1; i = e[i].next) { if (e[i].f) { w = e[i].w; if (dis[w] > dis[v] + e[i].c) { dis[w] = dis[v] + e[i].c; p[w] = i; if (!vst[w]) { vst[w] = true; q.push(w); } } } } } return dis[t] != inf; } int mcmf(int s, int t, int n) { int ans = 0, flow = inf, i; while (spfa(s, t, n)) { for (i = p[t]; i != -1; i = p[e[i].v]) if (e[i].f < flow) flow = e[i].f; for (i = p[t]; i != -1; i = p[e[i].v]) { e[i].f -= flow; e[i ^ 1].f += flow; } ans += dis[t] * flow; flow_sum += flow; } return ans; } int main() { //freopen("input","r",stdin); while (scanf("%d%d%d", &N, &M, &K) == 3 && N && M && K) { ans = 0; for (int i = 1; i <= N; i++) { for (int j = 1; j <= K; j++) { scanf("%d", &need[i][j]); } } for (int i = 1; i <= M; i++) { for (int j = 1; j <= K; j++) { scanf("%d", &supply[i][j]); } } bool flag = true; for (int k = 1; k <= K; k++) { //第k种货物 flow_sum = 0; tot = 0; memset(start, -1, sizeof(start)); for (int i = 1; i <= N; i++) { for (int j = 1; j <= M; j++) { scanf("%d", &cost); if (flag) add(j, M + i, 10000000, cost); } } for (int i = 1; i <= M; i++) { if (flag) add(0, i, supply[i][k], 0); } for (int i = 1; i <= N; i++) { if (flag) add(M + i, M + N + 1, need[i][k], 0); } if (flag) { ans += mcmf(0, N + M + 1, N + M + 2); good_sum = 0; for (int t = 1; t <= N; t++) good_sum += need[t][k]; if (flow_sum < good_sum) //所能达到的最大流小于需要的 flag = false; } } if (flag) printf("%d\n", ans); else printf("-1\n"); } }