这道题目分别求每一商品的最小费用,然后加起来就可以了。
但是调试了很久,郁闷,好多地方写的不对。也许是自己没看模版的原因。
记住:
1,反向边初始化为0;
2,spfa的标记。
3,初始化。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
#define INF 999999
int need[101][101];//i商店需要j的数量
int give[101][101];//i供货商给出j的数量
int fei[101][101][101];//j供货商给i商店k的费用
int cost[101][101];
struct list
{
int u;
int v;
int next;
}node[100001];
int nos;
int num;
int head[105];
void add(int l,int r ,int v)
{
node[num].u=r;
node[num].v=v;
node[num].next=head[l];
head[l]=num++;
}
int pre[105];
int spfa()
{
int visit[105];
int dist[105];
int i;
for(i=0;i<=nos;i++)dist[i]=INF;
memset(visit,0,sizeof(visit));
memset(pre,-1,sizeof(pre));
queue<int >q;
q.push(0);
dist[0]=0;
visit[0]=1;
while(!q.empty())
{
int e=q.front();
q.pop();
visit[e]=0;
for(i=head[e];i!=-1;i=node[i].next)
{
int r=node[i].u;
if(dist[r]>dist[e]+node[i].v&&cost[e][r])
{
pre[r]=e;
dist[r]=dist[e]+node[i].v;
if(!visit[r])
{
q.push(r);
visit[r]=1;
}
}
}
}
if(dist[nos]==INF)return 0;
else return 1;
}
void change()
{
int minx,i;
minx=INF;
for(i=nos;pre[i]!=-1;i=pre[i])
{
minx=min(minx,cost[pre[i]][i]);
}
for(i=nos;pre[i]!=-1;i=pre[i])
{
cost[pre[i]][i]-=minx;
cost[i][pre[i]]+=minx;
}
}
int main()
{
int N,M,K,i,j,k;
while(scanf("%d%d%d",&N,&M,&K)&&(N||M||K))
{
for(i=1;i<=N;i++)
for(j=1;j<=K;j++)
scanf("%d",&need[i][j]);
for(i=1;i<=M;i++)
for(j=1;j<=K;j++)
scanf("%d",&give[i][j]);
for(k=1;k<=K;k++)
for(i=1;i<=N;i++)
for(j=1;j<=M;j++)
scanf("%d",&fei[i][j][k]);
for(k=1;k<=K;k++)
{
int n1,n2;
n1=n2=0;
for(i=1;i<=N;i++)n1+=need[i][k];
for(i=1;i<=M;i++)n2+=give[i][k];
if(n1>n2)break;
}
if(k!=K+1)
{
printf("-1\n");
continue;
}
int sumuse;
sumuse=0;
nos=N+M+1;
for(k=1;k<=K;k++)
{
num=0;
memset(cost,0,sizeof(cost));
memset(head,-1,sizeof(head));
for(j=1;j<=M;j++)
{
add(0,j,0);
add(j,0,0);
cost[0][j]=give[j][k];
cost[j][0]=0;
}
for(i=1;i<=N;i++)
{
add(i+M,nos,0);
add(nos,i+M,0);
cost[i+M][nos]=need[i][k];
cost[nos][i+M]=0;
}
for(i=1;i<=N;i++)
{
for(j=1;j<=M;j++)
{
add(j,i+M,fei[i][j][k]);
add(i+M,j,-fei[i][j][k]);
cost[j][i+M]=INF;
cost[i+M][j]=0;
}
}
while(spfa())
{
change();
}
for(j=1;j<=M;j++)
{
for(i=1;i<=N;i++)
{
sumuse+=fei[i][j][k]*(INF-cost[j][i+M]);
}
}
}
printf("%d\n",sumuse);
}
return 0;
}