Poj 2516 Minimum Cost

题意大意:有N个客户,M个仓库,和K种货物。已知每个客户需要每种货物的数量,每个仓库存储每种货物的数量,每个仓库运输各种货物去各个客户的单位费用。判断所有的仓库能否满足所有客户的需求,如果可以,求出最少的运输总费用。

思路:最小费用最大流,这道题我是直接用了模板。

#include<iostream>
using namespace std;
#include <memory.h>
const int inf = 99999999;
const int Max = 110;
int get_min( int a, int b ) {
	if (a>b)
		return b;
	return a;
}  
int n, ans;
int cap[Max][Max], pre[Max];
int cost[Max][Max], dis[Max];
int que[Max];
bool vis[Max];

bool spfa(){                  //  源点为0,汇点为n。
    int u,i, head = 0, tail = 1;
    for(i = 0; i <= n; i ++){
        dis[i] = inf;
        vis[i] = false;
    }
    dis[0] = 0;
    que[0] = 0;
    
    while(tail != head){      //  循环队列。
        u = que[head];
		vis[u] = true;
        for(i = 0; i <= n; i ++)
            if(cap[u][i] && dis[i] > dis[u] + cost[u][i]){    //  存在路径,且权值变小。
                dis[i] = dis[u] + cost[u][i];
                pre[i] = u;
                if(!vis[i]){
                    vis[i] = true;
                    que[tail ++] = i;
                    if(tail == Max) tail = 0;
                }
            }
			vis[u] = false;
			head ++;
			if(head == Max) head = 0;
    }
    if(dis[n] == inf) return false;
    return true;
}

void end(){
    int i, sum = inf;
    for(i = n; i != 0; i = pre[i])
        sum = get_min(sum, cap[pre[i]][i]);
    for(i = n; i != 0; i = pre[i]){
        cap[pre[i]][i] -= sum;
        cap[i][pre[i]] += sum;
        ans += cost[pre[i]][i] * sum;   //  cost[][]记录的为单位流量费用,必须得乘以流量。
    }
}
int main()
{
	int N,M,K,i,j,k;
	int need[Max][Max],NeedK[Max];
	int have[Max][Max],HaveK[Max];

	while (scanf("%d%d%d",&N,&M,&K)&&N) {
		memset(NeedK,0,sizeof(NeedK));
		for (i=1;i<=N;i++) {
			for (j=1;j<=K;j++) {
				scanf("%d",&need[i][j]);
				NeedK[j]+=need[i][j];
			}
		}
		memset(HaveK,0,sizeof(HaveK));
		for (i=1;i<=M;i++) {
			for (j=1;j<=K;j++) {
				scanf("%d",&have[i][j]);
				HaveK[j]+=have[i][j];
			}
		}
		bool flag=true;
		for (i=1;i<=K;i++) {
			if (NeedK[i]>HaveK[i]) {
				flag=false;
				break;
			}
		}
		ans=0;
		n=N+M+1;
		for (k=1;k<=K;k++) {
			memset(cap,0,sizeof(cap));
			for (i=1;i<=N;i++) {
				for (j=1;j<=M;j++) {
					scanf("%d",&cost[j][M+i]);
					cost[M+i][j]=-cost[j][M+i];
					cap[j][M+i]=inf;
				}
			}
			if (!flag)
				continue;
			for (i=1;i<=M;i++) {
				cap[0][i] = have[i][k];
                cost[0][i] = cost[i][0] = 0;
            }
            for(i = 1; i <= N; i ++){
                cap[M+i][n] = need[i][k];
                cost[M+i][n] = cost[n][M+i] = 0;
			}
			while (spfa())
				end();
		}
		if (flag)
			cout << ans << endl;
		else 
			cout << -1 << endl;
	}
	return 0;
}


你可能感兴趣的:(存储)