2194. 负载平衡问题

题目链接

2194. 负载平衡问题

\(G\) 公司有 \(n\) 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。

如何用最少搬运量可以使 \(n\) 个仓库的库存数量相同。

搬运货物时,只能在相邻的仓库之间搬运。

数据保证一定有解。

输入格式

\(1\) 行中有 \(1\) 个正整数 \(n\),表示有 \(n\) 个仓库。

\(2\) 行中有 \(n\) 个正整数,表示 \(n\) 个仓库的库存量。

输出格式

输出最少搬运量。

数据范围

\(1 \le n \le 100\),
每个仓库的库存量不超过 \(100\)

输入样例:

5
17 9 14 16 4

输出样例:

11

解题思路

费用流

本题类似于 2192. 运输问题(即将超出平均值的点当作仓库,少于平均值的点当作商店)
建图:求出平均值 \(x\),建立源点 \(s\) 和汇点 \(t\),对于超出平均值的部分的点,\(s\) 向其连边,容量为超出平均值的部分,费用为 \(0\),另外其需要向相邻两点连边,容量足够大,费用为 \(1\),所有少于平均值的部分的点向 \(t\) 连边,容量为少于平均值的部分,费用为 \(0\),不难发现:可行流与实际问题一一对应,满流时即所有数都变为平均值的时候,且达到最大流时费用最少即移动的代价最少

  • 时间复杂度:\((knf)\)

贪心

本题同 122. 糖果传递

  • 时间复杂度:\(O(n)\)

代码

  • 费用流
// Problem: 负载平衡问题
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/2196/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=105,M=N*6,inf=1e9;
int n,a[N],S,T;
int h[N],e[M],w[M],f[M],ne[M],idx;
int incf[N],d[N],pre[N],q[N];
bool st[N];
void add(int a,int b,int c,int d)
{
	e[idx]=b,f[idx]=c,w[idx]=d,ne[idx]=h[a],h[a]=idx++;
	e[idx]=a,f[idx]=0,w[idx]=-d,ne[idx]=h[b],h[b]=idx++;
}
bool spfa()
{
	memset(d,0x3f,sizeof d);
	memset(incf,0,sizeof incf);
	d[S]=0,incf[S]=inf,q[0]=S;
	int hh=0,tt=1;
	while(hh!=tt)
	{
		int x=q[hh++];
		if(hh==N)hh=0;
		st[x]=false;
		for(int i=h[x];~i;i=ne[i])
		{
			int y=e[i];
			if(d[y]>d[x]+w[i]&&f[i])
			{
				d[y]=d[x]+w[i];
				pre[y]=i;
				incf[y]=min(incf[x],f[i]);
				if(!st[y])
				{
					q[tt++]=y;
					if(tt==N)tt=0;
					st[y]=true;
				}
			}
		}
	}
	return incf[T]>0;
}
int EK()
{
	int cost=0;
	while(spfa())
	{
		int t=incf[T];
		cost+=t*d[T];
		for(int i=T;i!=S;i=e[pre[i]^1])f[pre[i]]-=t,f[pre[i]^1]+=t;
	}
	return cost;
}
int main()
{
	memset(h,-1,sizeof h);
    scanf("%d",&n);
    int s=0;
    S=0,T=n+1;
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&a[i]);
    	s+=a[i];
    }
    s/=n;
    for(int i=1;i<=n;i++)
    {
    	if(a[i]>s)add(S,i,a[i]-s,0);
    	else if(a[i]<s)add(i,T,s-a[i],0);
    	add(i,i<n?i+1:1,inf,1);
    	add(i,i>1?i-1:n,inf,1);
    }
    printf("%d",EK());
    return 0;
}
  • 贪心
// Problem: 负载平衡问题
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/2196/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=105;
int n,a[N],b[N];
int main()
{
    scanf("%d",&n);
    int s=0,avg=0;
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&a[i]);
    	s+=a[i];
    }
    avg=s/n;
    for(int i=2;i<=n;i++)b[i]=b[i-1]+a[i]-avg;
	nth_element(b+1,b+(n+1)/2,b+1+n);
	int res=0;
	for(int i=1;i<=n;i++)
		res+=abs(b[i]-b[(n+1)/2]);
	printf("%d",res);
    return 0;
}
posted @ 2022-12-01 22:02  zyy2001  阅读(15)  评论(0编辑  收藏  举报