题意:
有N个零售商..有M个仓库...有K种物品要卖...现在告诉每个零售商对每种商品的需求量..每个仓库对每种商品的存储量..以及每个仓库买每种商品到零售商的价格(一次性..不是单价..理解为距离更和谐...)..问最少要花费多少使得N个零售商都满足需求...
题解:
构图很简单了...但要注意的是.. TLE...解决方法是分k次做..
Program:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#define MAXN 8005
#define MAXM 8000005
#define oo 1000000007
#define ll long long
using namespace std;
struct MCMF
{
struct node
{
int x,y,c,v,next;
}line[MAXM];
int Lnum,_next[MAXN],pre[MAXN],dis[MAXN],flow,cost;
bool inqueue[MAXN];
void initial(int n)
{
Lnum=-1;
for (int i=0;i<=n;i++) _next[i]=-1;
}
void addline(int x,int y,int c,int v)
{
line[++Lnum].next=_next[x],_next[x]=Lnum;
line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c,line[Lnum].v=v;
line[++Lnum].next=_next[y],_next[y]=Lnum;
line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0,line[Lnum].v=-v;
}
bool SPFA(int s,int e)
{
int x,k,y;
queue<int> Q;
while (!Q.empty()) Q.pop();
memset(dis,0x7f,sizeof(dis));
memset(inqueue,false,sizeof(inqueue));
Q.push(s);
dis[s]=0,pre[s]=-1;
while (!Q.empty())
{
x=Q.front(),Q.pop(),inqueue[x]=false;
for (k=_next[x];k!=-1;k=line[k].next)
if (line[k].c)
{
y=line[k].y;
if (dis[y]>dis[x]+line[k].v)
{
dis[y]=dis[x]+line[k].v;
pre[y]=k;
if (!inqueue[y])
{
inqueue[y]=true;
Q.push(y);
}
}
}
}
if (dis[e]>oo) return false;
flow=oo,cost=0;
for (k=pre[e];k!=-1;k=pre[line[k].x])
flow=min(flow,line[k].c),cost+=line[k].v;
cost*=flow;
for (k=pre[e];k!=-1;k=pre[line[k].x])
line[k].c-=flow,line[k^1].c+=flow;
return true;
}
void MinCostMaxFlow(int s,int e,int &Aflow,int &Acost)
{
Aflow=0,Acost=0;
while (SPFA(s,e))
{
Aflow+=flow;
Acost+=cost;
}
}
}T;
int A[55][55],B[55][55],dis[55][55][55];
int main()
{
int Af,Ac,ansc,sum,s,e,x,t,i,j,n,m,k;
while (~scanf("%d%d%d",&n,&m,&k) && n)
{
for (i=1;i<=n;i++)
for (t=1;t<=k;t++)
scanf("%d",&A[t][i]);
for (i=1;i<=m;i++)
for (t=1;t<=k;t++)
scanf("%d",&B[t][i]);
for (t=1;t<=k;t++)
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
scanf("%d",&dis[t][i][j]);
ansc=0;
for (t=1;t<=k;t++)
{
s=(n+m)+3,e=s+1,T.initial(e),sum=0;
for (i=1;i<=n;i++) T.addline(s,i,A[t][i],0),sum+=A[t][i];
for (i=1;i<=m;i++) T.addline(i+n,e,B[t][i],0);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
T.addline(i,j+n,oo,dis[t][i][j]);
T.MinCostMaxFlow(s,e,Af,Ac);
if (Af!=sum) break;
ansc+=Ac;
}
if (t<=k) printf("-1\n");
else printf("%d\n",ansc);
}
return 0;
}