这道题目分别求每一商品的最小费用,然后加起来就可以了。
但是调试了很久,郁闷,好多地方写的不对。也许是自己没看模版的原因。
记住:
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; }