POJ-2516-Minimum Cost

POJ-2516-Minimum Cost

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

N個顧客,M個供應商,K種貨物,給出一些供求關係,求滿求條件的最小代價

最小費用最大流,對k種貨物的每一種求一次最小費用,相加即可

#include<stdio.h>
#include<string.h>
#include<math.h>
#define maxn 300
#define INF 0x7fffffff
int min(int x,int y)
{
	return x<y?x:y;
}
int map[maxn][maxn],vis[maxn],cap[maxn][maxn],dis[maxn];
int que[maxn],pre[maxn];
int num,ans;
int SPFA() 
{
	int i,k;
	int head,tail;
	memset(vis,0,sizeof(vis));
	for(i=0;i<=num;i++)
	dis[i]=INF;
	dis[0]=0;
	vis[0]=1;
	head=tail=0;
	que[0]=0;
	tail++;
	while(head<tail)
	{
       k=que[head];
	   vis[k]=0;
	   for(i=0;i<=num;i++)
	   {
		   if(cap[k][i]&&dis[i]>dis[k]+map[k][i])
		   {
			   dis[i]=dis[k]+map[k][i];
			   pre[i]=k;
			   if(!vis[i])
			   {
				   vis[i]=1;
				   que[tail++]=i;
			   }
		   }
	   }
	   head++;
	}
	if(dis[num]<INF)
	return 1;
	return 0;
}
void end()
{
	int i,sum=INF;
	for(i=num;i!=0;i=pre[i])
	sum=min(sum,cap[pre[i]][i]);
	for(i=num;i!=0;i=pre[i])
	{
		cap[pre[i]][i]-=sum;
		cap[i][pre[i]]+=sum;
		ans+=map[pre[i]][i]*sum;
	}
}
int main()
{
	int N,M,K,i,j,k;
	int need[maxn][maxn],needk[maxn];
	int have[maxn][maxn],havek[maxn];
	int flag;
	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];
		}
		flag=1;
		for(i=1;i<=K;i++)
		if(needk[i]>havek[i])
		{
			flag=0;
			break;
		}
		ans=0;
		num=N+M+1;
		for(k=1;k<=K;k++)   //處理每一種貨物
		{
			memset(cap,0,sizeof(cap)); 
			memset(map,0,sizeof(map));
			for(i=1;i<=N;i++)
			for(j=1;j<=M;j++)
			{
				scanf("%d",&map[j][M+i]);
				map[M+i][j]=-map[j][M+i];
				cap[j][M+i]=have[j][k];
				cap[M+i][j]=0;
			}
		    if(!flag)
			continue;
			for(i=1;i<=M;i++)  //源點向供應商建邊
			{
				cap[0][i]=have[i][k];
				map[0][i]=map[i][0]=0;
			}
			for(i=1;i<=N;i++) //顧客向匯點建邊
			{
				cap[M+i][num]=need[i][k];
				map[M+i][num]=map[num][M+i]=0;
			}
			while(SPFA())
			end();
		}
		if(flag)
		printf("%d\n",ans);
		else
	    printf("-1\n");
	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章