hdoj--2282--Chocolate(最小费用)

Chocolate

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 577    Accepted Submission(s): 290



Problem Description
Lethe loves eating chocolates very much. In Lethe's birthday, her good friend echo brings N boxes to her, and makes the boxes on the circle. Furthermore, echo tells Lethe that there are many chocolates in the boxes, but the total number of chocolates doesn't exceed N. Also, echo wants Lethe to displace the chocolates in such a way that in each box remains no more than one chocolate. In one move she can shift one chocolate from current box to its neighboring box. (Each box has two neighboring boxes). Can you tell Lethe the minimum number of move to achieve this goal?
 

Input
There are multi-cases (The total number of cases won't exceed 20). First line is an integer N(1<=N<=500), the total number of boxes. Then N lines follow, each line includes a number, indicates the number of chocolates in the box.
 

Output
Output the minimum number of move.
 

Sample Input
10 1 3 3 0 0 2 0 0 0 0
 

Sample Output
9
 

Source
HDU 8th Programming Contest Site(2)

1:源点到每一个盒子建边,容量是每个盒子的巧克力数量,费用为零
2:汇点到每一个盒子建边,容量为一,因为最终每个盒子的巧克力数量不能超过1,费用用为零
3:每个盒子向邻近的盒子建边,容量为INF,因为没有规定上限,费用为1,因为每一步最多转移一个

#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
#define MAXN 600
#define MAXM 10000
#define INF 0x3f3f3f3f
int head[MAXN],cue[MAXN],pre[MAXN];
int dis[MAXN],vis[MAXN];
int n,top;
struct node
{
	int u,v,cap,flow,cost,next;
}edge[MAXM];
void init()
{
	top=0;
	memset(head,-1,sizeof(head));
}
void add(int u,int v,int w,int c)
{
	node E1={u,v,w,0,c,head[u]};
	edge[top]=E1;
	head[u]=top++;
	node E2={v,u,0,0,-c,head[v]};
	edge[top]=E2;
	head[v]=top++;
}
void getmap()
{
	int a;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a);
		add(0,i,a,0);
		add(i,n+1,1,0);
		if(i==1)
		{
			add(1,n,INF,1);
			add(1,2,INF,1);
		}
		else if(i==n)
		{
			add(n,n-1,INF,1);
			add(n,1,INF,1);
		}
		else
		{
			add(i,i-1,INF,1);
			add(i,i+1,INF,1);
		}
	}
}
bool SPFA(int s,int t)
{
	queue<int>q;
	memset(dis,INF,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(pre,-1,sizeof(pre));
	dis[s]=0;
	vis[s]=1;
	q.push(s);
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			node E=edge[i];
			if(dis[E.v]>dis[E.u]+E.cost&&E.cap>E.flow)
			{
				dis[E.v]=dis[E.u]+E.cost;
				pre[E.v]=i;
				if(!vis[E.v])
				{
					vis[E.v]=1;
					q.push(E.v);
				}
			}
		}
	}
	return pre[t]!=-1;
}
void mcmf(int s,int t,int &cost)
{
	cost=0;
	while(SPFA(s,t))
	{
		int MIN=INF;
		for(int i=pre[t];i!=-1;i=pre[edge[i^1].v])
		{
			node E=edge[i];
			MIN=min(MIN,E.cap-E.flow);
		}
		for(int i=pre[t];i!=-1;i=pre[edge[i^1].v])
		{
			edge[i].flow+=MIN;
			edge[i^1].flow-=MIN;
			cost+=edge[i].cost*MIN;
		}
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		init();
		getmap();
		int cost;
		mcmf(0,n+1,cost);
		printf("%d
",cost);
	}
	return 0;
}


 
原文地址:https://www.cnblogs.com/playboy307/p/5273604.html