題目:http://poj.org/problem?id=2516
原始碼:
#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#define INF 1e9#define MAXN 110const int N = 200, M = 10010;using namespace std;int n,m,k,ans;int cost[MAXN][MAXN][MAXN];int need[MAXN][MAXN],sale[MAXN][MAXN];int sasum[MAXN],nesum[MAXN];struct MinCostMaxFlow { int e, ev[M], nxt[M], head[N]; int cost[M], dist[N]; int cap[M]; int pnt[N], road[N], q[N], bg, ed; bool vis[N]; void init(int n) { e = 0; for(int i=0;i<=n;i++) head[i]=-1; } void addedge(int u, int v, int f, int c) { //u->v flow=f, cost=c ev[e]=v; cap[e]=f; cost[e]=c; nxt[e]=head[u]; head[u]=e++; ev[e]=u; cap[e]=0; cost[e]=-c; nxt[e]=head[v]; head[v]=e++; } bool spfa(int s, int t, int n) { for(int i=0;i<=n;i++) { dist[i]=INF; vis[i]=0; } bg = ed = dist[s] = 0; pnt[s] = s; q[ed++] = s; while (bg != ed) { int u = q[bg++]; vis[u] = 0; if (bg == N) bg = 0; for (int i = head[u]; ~i; i = nxt[i]) { if (cap[i] <= 0) continue; int v = ev[i]; if (dist[v] > dist[u] + cost[i]) { dist[v] = dist[u] + cost[i]; pnt[v] = u; road[v] = i; if (!vis[v]) { q[ed++] = v; vis[v] = 1; if(ed == N)ed = 0; } } } } return dist[t] != INF;} void mincost(int s, int t, int n, int &f, int &c) { c = f = 0; while(spfa(s, t, n)){ int minf = INF; for(int u = t; u != s; u = pnt[u]) minf = min(minf, cap[road[u]]); for(int u = t; u != s; u = pnt[u]){ cap[road[u]] -= minf; cap[road[u] ^ 1] += minf; } f += minf; c += minf * dist[t]; } }};int solve(int x){ MinCostMaxFlow ans; int ans1,ans2; ans.init(m+n+1); for(int i=1;i<=m;i++) ans.addedge(0,i,sale[i][x],0); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) ans.addedge(i,j+m,INF,cost[x][j][i]); for(int i=1;i<=n;i++) ans.addedge(m+i,m+n+1,need[i][x],0); ans.mincost(0,m+n+1,m+n+2,ans1,ans2); return ans2;}int main(){ // freopen("D:\\a.txt","r",stdin); while(true) { memset(sasum,0,sizeof(sasum)); memset(nesum,0,sizeof(nesum)); scanf("%d %d %d",&n,&m,&k); if(!n&&!m&&!k) break; for(int i=1;i<=n;i++) { for(int j=1;j<=k;j++) { scanf("%d",&need[i][j]); nesum[j]+=need[i][j]; } } for(int i=1;i<=m;i++) { for(int j=1;j<=k;j++) { scanf("%d",&sale[i][j]); sasum[j]+=sale[i][j]; } } for(int p=1;p<=k;p++) for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&cost[p][i][j]); int flag=1; for(int i=1;i<=k;i++) if(sasum[i]<nesum[i]) { printf("-1\n"); flag=0; break; } if(!flag) continue; ans=0; for(int i=1;i<=k;i++) { int tmp=solve(i); ans+=tmp; } if(flag) printf("%d\n",ans); } return 0;}