POJ 2516 Minimum Cost 网络流

http://poj.org/problem?id=2516

题意:

有 n 个商店,k种物品和 m 个供货商,让你求进满足商店需求的货物的最小花费?

有必要说一下输入数据。

首先n ,k ,m 

然后是一个n*k的矩阵,n个商店对每种货物的需求,mat[i][j]=x表示第 i 个商店需要第 j 种货物 x个 

然后是m * k 的矩阵,m个供货商可以供k种货物的数量,mat[i][j]=x表示第 i 个供货商 提供第 j 中货物 x 个

接下来是 k 个 n * m 的矩阵,第k个矩阵mat中mat[i][j]=x表示第 k个货物,由 j供应商发货给 i 商店的价格x

如果供不应求输出-1。

题解:k次最小费用流

注意,中间判断出了供不应求,还是一定要把剩下的数据读完再输出-1;

扫描二维码关注公众号,回复: 2670712 查看本文章

代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;
const int maxn=800;
const int maxm=50005;
const int inf=0x3f3f3f3f;
struct Edge{
	int to,next,cap,flow,cost;
}edge[maxm];
int tol;
int head[maxn];
int pre[maxn],dis[maxn];
bool vis[maxn];
int N;
void init(int n){
	N=n;
	tol=0;
	memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost){
	edge[tol].to=v;
	edge[tol].cost=cost;
	edge[tol].cap=cap;
	edge[tol].flow=0;
	edge[tol].next=head[u];
	head[u]=tol++;
	edge[tol].to=u;
	edge[tol].cost=-cost;
	edge[tol].cap=0;
	edge[tol].flow=0;
	edge[tol].next=head[v];
	head[v]=tol++;
}
bool spfa(int s,int t){
	queue<int>q;
	int i;
	for(i=0;i<N;i++){
		dis[i]=inf;
		vis[i]=false;
		pre[i]=-1;
	}
	dis[s]=0;
	vis[s]=true;
	q.push(s);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=false;
		for(i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
				dis[v]=dis[u]+edge[i].cost;
				pre[v]=i;
				if(!vis[v]){
					vis[v]=true;
					q.push(v);
				}
			}
		}
	}
	if(pre[t]==-1)return false;
	else return true;
}
int mincostmaxflow(int s,int t,int &cost){
	int flow=0;
	cost=0;
	while(spfa(s,t)){
		int Min=inf;
		int i;
		for(i=pre[t];i!=-1;i=pre[edge[i^1].to]){
			if(Min>edge[i].cap-edge[i].flow)Min=edge[i].cap-edge[i].flow;
		}
		for(i=pre[t];i!=-1;i=pre[edge[i^1].to]){
			edge[i].flow+=Min;
			edge[i^1].flow-=Min;
			cost+=edge[i].cost*Min;
		}
		flow+=Min;
	}
	return flow;
}
int k;
int shopkeeper[600][600],supply[600][600];
int mp[600][600];
int main()
{
	int i,j,n,m,t;
	while(~scanf("%d%d%d",&n,&m,&k)){
		int ans_=0;
		if(n+m+k==0)break;
		for(i=0;i<n;i++)
			for(j=0;j<k;j++)scanf("%d",&shopkeeper[i][j]);
		for(i=0;i<m;i++)
			for(j=0;j<k;j++)scanf("%d",&supply[i][j]);
		int flag=0;
		for(t=0;t<k;t++){
			int ans=0;
			init(200);
			for(i=0;i<n;i++)
				for(j=0;j<m;j++)scanf("%d",&mp[i][j]);
			for(i=0;i<n;i++){
				addedge(i+1,n+m+1,shopkeeper[i][t],0);
				for(j=0;j<m;j++){
					addedge(j+n+1,i+1,inf,mp[i][j]);
				}
			}
			for(j=0;j<m;j++)addedge(0,j+n+1,supply[j][t],0);
			int mincost;
			for(i=0;i<n;i++)ans+=shopkeeper[i][t];
			if(ans==mincostmaxflow(0,n+m+1,mincost))ans_+=mincost;
			else {
				flag=1;
			}
		}
		if(flag)printf("-1\n");
		else printf("%d\n",ans_);
	}
//    cout << "Hello world!" << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/nwpu2017300135/article/details/81456511
今日推荐