【网络流24题】【Luogu P4016】 负载平衡问题

可能更好的阅读


题目大意:

\(n\)个仓库,要把所有仓库的存库数统一,问一共要搬多少物品。

正文:

首先这是费用流。

要统一存库数,统一的存款数就是所有存库数的平均值,那就是说,如果存库数小于平均值就要进货,如果存库数大于平均值就要出货。

那我们就把每个仓库作两份(假设对于第\(i\)个仓库,两份分别是 \(a_{i_A}\)\(a_{i_B}\)),样例如图:

图1

如果要进货,\(A\) 和源点 \(S\) 连接,否则 \(B\) 和汇点 \(T\) 连接,费用是 \(|\text{存库数-平均值}|\),样例如图:

图2

横线上是费用。

题目中说,"\(G\) 公司有 \(n\) 个沿铁路运输线 环形排列 的仓库",相邻的结点是相连的,样例如图:

图3

详见代码。

代码:

for (int i = 1; i <= n; i++)
{ 
	scanf("%d", &x[i]);
	sum += x[i];
}
sum /= n;       // 取平均值
for (int i = 1; i <= n; i++)
{
	x[i] -= sum;
	if(x[i] < 0)                 //和源点和汇点连线
	{
		Add(i + n, t, -x[i], 0);
	} 
	else 
	{
		Add(s, i, x[i], 0);
	}
	if(i - 1 > 0)              //以下互相连线
	{
		Add(i, i - 1, INF, 1);
		Add(i, i + n - 1, INF, 1);
	}
	if(i + 1 <= n)
	{
		Add(i, i + 1, INF, 1);
		Add(i, i + 1 + n, INF, 1);
	}
}
Add(1, n, INF, 1);
Add(1, n << 1, INF, 1);
Add(n, 1, INF, 1);
Add(n, 1 + n, INF, 1);
MCMF();     //费用流
printf("%d\n", mincost);
posted @ 2020-01-23 19:28  Jayun  阅读(152)  评论(2编辑  收藏  举报