P1954【线性规划与网络流24题 19】负载平衡问题
时间限制 : 10000 MS 空间限制 : 65536 KB
问题描述
G公司有n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使n个仓库的库存数量相同。
搬运货物时,只能在相邻的仓库之间搬运。
对于给定的n个环形排列的仓库的库存量,编程计算使n个仓库的库存数量相同的最少搬运量。
输入格式
第1行中有1个正整数n(n<=100),表示有n个仓库。第2行中有n个正整数,表示n个仓库的库存量。
输出格式
一个整数,表示最少搬运量
样例输入
5
17 9 14 16 4
样例输出
11
题解:
每个人之间连一条容量无限,距离为1的边;
注意他是一个环1与n要连一条边
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define inf 99999999
#define maxn 805
int n,sum,s,p;
int cnt=1;
int a[105];
int path[maxn],p2[maxn];
int Next[maxn],Last[maxn],End[maxn],con[maxn],Len[maxn];
bool mark[maxn];
int dis[maxn];
int start=0,mincost;
bool spfa()
{
int i,x,y;
queue<int>q;
for(i=start;i<=n+1;i++) dis[i]=inf;
memset(mark,false,sizeof(mark));
q.push(start);
mark[start]=true;
dis[start]=0;
while(q.size())
{
int x=q.front();
q.pop();
mark[x]=false;
for(i=Last[x];i;i=Next[i])
{
int en=End[i];
if(con[i]>0&&dis[en]>dis[x]+Len[i])
{
dis[en]=dis[x]+Len[i];
path[en]=x;
p2[en]=i;
if(mark[en]==0){
q.push(en);
mark[en]=true;
}
}
}
}
if(dis[n+1]<inf) return true;
else return false;
}
void insert(int x,int y,int z,int w)
{
cnt++;
Next[cnt]=Last[x];
Last[x]=cnt;
End[cnt]=y;
Len[cnt]=w;
con[cnt]=z;
}
void addflow()
{
int flow=inf,cost=0,p=0;
for(int i=n+1;i;i=path[i])
{
p=p2[i];
flow=min(flow,con[p]);
}
mincost+=flow*dis[n+1];
for(int i=n+1;i;i=path[i])
{
p=p2[i];
con[p]-=flow;
con[p^1]+=flow;
}
}
int main()
{
int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++){ scanf("%d",&a[i]);sum+=a[i];}
p=sum/n;
for(i=1;i<=n;i++){
insert(0,i,a[i],0);
insert(i,0,0,0);
}
for(i=1;i<=n-1;i++)
{
insert(i,i+1,inf,1);
insert(i+1,i,0,-1);
insert(i+1,i,inf,1);
insert(i,i+1,0,-1);
}
insert(1,n,inf,1);
insert(n,1,0,-1);
insert(n,1,inf,1);
insert(1,n,0,-1);
for(i=1;i<=n;i++)
{
insert(i,n+1,p,0);
insert(n+1,i,0,0);
}
while(spfa()) addflow();
cout<<mincost;
}