#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <queue>
#define LL long long
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1e3+10;
struct node{
int to,flow,cost;
int next;
}edge[10000];
int head[N];//前向星
int sK[N][N];//商店需求量
int hK[N][N];//仓库存储量
int mK[N][N];//仓库到商店的费用
int sN[N];//所有商店一共需要第K种物品多少
int hN[N];//所有仓库一共存储第K种物品多少
int pre[N];//记录前驱,记录的是edge的编号
int n,m,k,top;
int s,e,ans;
void init(){
top = 0,s = 0,e = n+m+1;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int f,int c){
edge[top]={v,f,c,head[u]};
head[u] = top++;
}
int dis[N];
bool vis[N];
bool EK_spfa(){
queue<int>q;
memset(dis,inf,sizeof(dis));
memset(vis,false,sizeof(vis));
memset(pre,-1,sizeof(pre));
dis[s] = 0;
vis[s] = true;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; ~i; i = edge[i].next){
if(dis[edge[i].to] > dis[u]+edge[i].cost&&edge[i].flow){
dis[edge[i].to] = dis[u]+edge[i].cost;
pre[edge[i].to] = i;
if(!vis[edge[i].to]){
vis[edge[i].to] = true;
q.push(edge[i].to);
}
}
}
}
return pre[e]!=-1;
}
bool EK_Max_Flow(int t){
int cost_ans,flow_ans,mn;
cost_ans = flow_ans = 0;
while(EK_spfa()){
mn = inf;
for(int i = pre[e]; ~i; i = pre[edge[i^1].to]){
mn = min(mn,edge[i].flow);
}
for(int i = pre[e]; ~i; i = pre[edge[i^1].to]){
edge[i].flow -= mn;
edge[i^1].flow += mn;
cost_ans += edge[i].cost*mn;
}
flow_ans += mn;
}
if(flow_ans != sN[t])return true;
ans += cost_ans;
return false;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&k),n||m||k){
//商店
memset(sN,0,sizeof(sN));
memset(hN,0,sizeof(hN));
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= k; ++j){
scanf("%d",&sK[i][j]);
sN[j] += sK[i][j];
}
}
//仓库
for(int i = 1; i <= m; ++i){
for(int j = 1; j <= k; ++j){
scanf("%d",&hK[i][j]);
hN[j] += hK[i][j];
}
}
bool flag = false;
for(int i = 1; i <= k; ++i){
if(sN[i]>hN[i])flag=true;
}
ans = 0;
for(int i = 1; i <= k; ++i){
for(int j = 1; j <= n; ++j){
for(int l = 1; l <= m; ++l){
scanf("%d",&mK[j][l]);
}
}
if(flag)continue;
init();
for(int j = 1; j <= m; ++j){
add(s,j,hK[j][i],0);
add(j,s,0,0);
}
for(int j = 1; j <= n; ++j){
add(j+m,e,sK[j][i],0);
add(e,j+m,0,0);
}
for(int j = 1; j <= m; ++j){
for(int l = 1; l <= n; ++l){
add(j,l+m,inf,mK[l][j]);
add(l+m,j,0,-mK[l][j]);
}
}
flag = EK_Max_Flow(i);
}
if(flag){
printf("-1\n");
}
else{
printf("%d\n",ans);
}
}
return 0;
}
最小费用最大流poj2516
最新推荐文章于 2019-09-22 16:55:58 发布