题目大意:就是有n个商家然后n行是对应每个商家对k件物品的需求量。然后m行分别代表每个供应区可以提供k件物品的数量,下面是k个n*m的矩阵代表第k个物品,从j供应区运到i需求商的费用。
思路:我们可以分k次求最小费用最大流。这题挺简单的就是源点连供应区,供应区连供应商,供应商连汇点。但是注意数组一定要开大!否则可能WA。能想到的话注意是不是即使刚开始满足供应,但是最后不一定可以供应的问题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
#define MAX 1000
#define inf 0x3f3f3f3f
using namespace std;
struct no{
int d[64];
}p[64];
struct nod{
int nu[64];
}p1[64];
struct node{
int a[64][64];
}p2[64];
struct node1{
int to,next,w,c;
}q[30024];
int star,en,head[30024],cnt,flow,minflow,cost,dis[3024],qu[10024],cur[10024];
bool vis[3024];
int f[10024];
void bu(int a,int b,int w,int c){
q[cnt].to=b;
q[cnt].w=w;
q[cnt].c=c;
q[cnt].next=head[a];
head[a]=cnt++;
q[cnt].to=a;
q[cnt].w=0;
q[cnt].c=-c;
q[cnt].next=head[b];
head[b]=cnt++;
}
bool SPFA(){
memset(vis,false,sizeof (vis) );
memset(dis,inf,sizeof (dis) );
dis[star]=0;
vis[star]=true;
cur[en]=cur[star]=-1;
f[star]=inf;
int f1,f2;f1=f2=0;
qu[f1++]=star;
while(f1>f2){
int u=qu[f2++];
vis[u]=false;
for(int i=head[u];~i;i=q[i].next){
int v=q[i].to;
if(dis[v]>dis[u]+q[i].c&&q[i].w>0){
dis[v]=dis[u]+q[i].c;
f[v]=min(f[u],q[i].w);
cur[v]=i;
if(!vis[v]){
vis[v]=true;
qu[f1++]=v;
}
}
}
}
if(dis[en]>=inf)return false;
flow+=f[en];
cost+=f[en]*dis[en];
for(int i=cur[en];~i;i=cur[q[i^1].to]){
q[i].w-=f[en];
q[i^1].w+=f[en];
}
return true;
}
int main(){
int n,m,i,j,k,SS;
while(~scanf("%d%d%d",&n,&m,&k)){
SS=0;
if(!n&&!m&&!k)
break;
cost=0;
for(i=1;i<=n;i++){
for(j=1;j<=k;j++){
scanf("%d",&p[i].d[j]);
}
}
for(i=1;i<=m;i++){
for(j=1;j<=k;j++)
scanf("%d",&p1[i].nu[j]);
}
for(i=1;i<=k;i++){
for(int x=1;x<=n;x++){
for(int y=1;y<=m;y++){
scanf("%d",&p2[i].a[x][y]);
}
}
}
bool bj=false;
for(j=1;j<=k;j++){
int x=0,y=0;
for(i=1;i<=n;i++){
x+=p[i].d[j];
}
for(i=1;i<=m;i++){
y+=p1[i].nu[j];
}
if(x>y){
bj=true;break;
}
}
if(bj){
printf("-1\n");continue;
}
bool bj1=false;
for(int x=1;x<=k;x++){
SS=flow=cnt=star=0;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)
SS+=p[i].d[x];
en=n+m+1;
for(i=1;i<=m;++i)
bu(star,i,p1[i].nu[x],0);
for( i=1;i<=n;i++ )
for( j=1;j<=m;j++)
bu(j,i+m,min(p[i].d[x],p1[j].nu[x]),p2[x].a[i][j]);
for(i=1;i<=n;++i)
bu(i+m,en,p[i].d[x],0);
while(SPFA());
if(flow<SS)
bj1=true;
}
if(bj1)
puts("-1");
else
printf("%d\n",cost);
}
}