Luogu P4016 负载平衡问题
传说中的网络流24题之一,我刷的第二题菜。
据说这种东西做完了就可以有质的飞越?不过看着这些Luogu评级就有点蒙蔽。
首先我们看一下题目发现这不是均分纸牌的加强板吗,但是那个环的操作极大地限制了我的思想。
我们考虑用费用流求解。
首先拆点,把每一个仓库拆成两个,一个\(x_i\)表示供给别人的货物,一个\(y_i\)表示别人供给的货物。然后建立超级源点\(S\)和超级汇点\(T\)。
我们可以很容易地知道:每一个仓库最后剩下的货物数量必定是总货物数量的平均数。
然后就很简单了。我们将所有的货物量\(a_i\)减去平均数,得到新的\(a_i\)。然后讨论:
- 当\(a_i<0\)时,这个节点需要运入货物。所以我们呢将\(S\)与\(x_i\)相连,容量就是\(-a_i\),费用为\(0\)(至于为什么为\(0\)等下会解释)
- 当\(a_i>0\)时,这个节点需要运出货物。所以我们呢将\(y_i\)与\(T\)相连,容量就是\(a_i\),费用为\(0\)
然后对于相邻节点还可以连边:
- 将\(x_i\)与\(y_j\)相连,容量为\(\infty\),费用为\(1\)。这个很好理解吧,相邻的需要直接运输过去即可,费用就是运输量。
- 将\(x_i\)与\(x_j\)相连,容量为\(\infty\),费用为\(1\)。这个还是要想一下的,相当于将\(x_i\)的货物暂时存放在\(x_j\)处,为其他的运输做准备。
然后由于所有的费用都在这些物体之间的运输中计算掉了,因此源汇点的费用就是\(0\)了。(其实也就是把那些供给的点连到一起方便跑而已,一个常见的技巧)
然后我们直接跑MCMF即可,然后引用一段著名的话:
最大流保证能够平衡货物,而最小费用流能保证运输的货物最少。
CODE
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=205,INF=2e9;
queue <int> q;
struct edge
{
int to,next,c,f;
}e[N<<3];
int head[N],dis[N],cap[N],a[N],pre[N],last[N],s,t,n,ave,cnt=-1;
bool vis[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void add(int x,int y,int c,int f)
{
e[++cnt].to=y; e[cnt].c=c; e[cnt].f=f; e[cnt].next=head[x]; head[x]=cnt;
}
inline void insert(int x,int y)
{
add(x,y,INF,1); add(y,x,0,-1); add(x,y+n,INF,1); add(y+n,x,0,-1);
}
inline bool SPFA(void)
{
memset(pre,-1,sizeof(pre));
memset(dis,63,sizeof(dis));
memset(cap,63,sizeof(cap));
memset(vis,0,sizeof(vis));
while (!q.empty()) q.pop();
q.push(s); vis[s]=1; dis[s]=0;
while (!q.empty())
{
int now=q.front(); q.pop(); vis[now]=0;
for (register int i=head[now];i!=-1;i=e[i].next)
if (e[i].c&&dis[e[i].to]>dis[now]+e[i].f)
{
dis[e[i].to]=dis[now]+e[i].f;
cap[e[i].to]=min(cap[now],e[i].c);
pre[e[i].to]=now; last[e[i].to]=i;
if (!vis[e[i].to]) vis[e[i].to]=1,q.push(e[i].to);
}
}
return pre[t]^-1;
}
inline void MCMF(void)
{
int tot=0;
while (SPFA())
{
tot+=cap[t]*dis[t]; int now=t;
while (now!=s)
{
e[last[now]].c-=cap[t];
e[last[now]^1].c+=cap[t];
now=pre[now];
}
}
printf("%d",tot);
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(n); s=0,t=(n<<1)+1;
memset(head,-1,sizeof(head));
memset(e,-1,sizeof(e));
for (i=1;i<=n;++i)
read(a[i]),ave+=a[i]; ave/=n;
for (i=1;i<=n;++i)
{
a[i]-=ave; if (a[i]>0) add(s,i,a[i],0),add(i,s,0,0); else add(i+n,t,-a[i],0),add(t,i+n,0,0);
if (i==1) insert(1,n),insert(1,2); else
if (i==n) insert(n,1),insert(n,n-1); else insert(i,i-1),insert(i,i+1);
}
MCMF(); return 0;
}
Luogu P4016 负载平衡问题的更多相关文章
- 洛谷 P4016负载平衡问题【费用流】题解+AC代码
洛谷 P4016负载平衡问题 P4014 分配问题[费用流]题解+AC代码 负载平衡问题 题目描述 GG 公司有n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n ...
- P4016 负载平衡问题 网络流
P4016 负载平衡问题 题目描述 GG 公司有 nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 nn个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运 ...
- P4016 负载平衡问题(最小费用最大流)
P4016 负载平衡问题 题目描述 GG 公司有 nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 nn 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬 ...
- P4016 负载平衡问题 网络流重温
P4016 负载平衡问题 这个题目现在第二次做,感觉没有这么简单,可能是我太久没有写这种题目了,基本上都忘记了,所以我连这个是费用流都没有看出来. 有点小伤心,知道是费用流之后,我居然还拆点了. 这个 ...
- 洛谷P4016负载平衡
题目 负载平衡问题是一个比较经典的网络流问题,但是该问题还有一个数学贪心法. 所以做这个题前,其实可以做一下均分纸牌问题. 均分纸牌问题 均分纸牌问题可以说是作为贪心的入门题. 做法 首先我们应当把原 ...
- (洛谷P2512||bzoj1045) [HAOI2008]糖果传递 || 洛谷P4016 负载平衡问题 || UVA11300 Spreading the Wealth || (洛谷P3156||bzoj3293) [CQOI2011]分金币
bzoj1045 洛谷P4016 洛谷P2512 bzoj3293 洛谷P3156 题解:https://www.luogu.org/blog/LittleRewriter/solution-p251 ...
- 洛谷 [P4016] 负载平衡问题
贪心做法 第一眼看见觉得和均分纸牌差不多,然而因为这是环形的,并不能用均分纸牌的方法做,但是均分纸牌的思想仍然适用 首先我们假设平均数为sum1. 那么对于第1个人,我们假设他给第N个人K个糖果, 第 ...
- 『题解』洛谷P4016 负载平衡问题
title: categories: tags: - mathjax: true --- Problem Portal Portal1:Luogu Portal2: LibreOJ Descripti ...
- P2512 [HAOI2008]糖果传递&&P3156 [CQOI2011]分金币&&P4016 负载平衡问题
P2512 [HAOI2008]糖果传递 第一步,当然是把数据减去平均数,然后我们可以得出一串正负不等的数列 我们用sum数组存该数列的前缀和.注意sum[ n ]=0 假设为链,那么可以得出答案为a ...
随机推荐
- Angular 2基础(一) 环境搭建
Angular2是一款开源JavaScript库,由Google维护,用来创建页面应用程序.正式发布于2016年9月,基于ES6开发. 一.准备工作 使用Angular2开发,需要预先做一些配置上的配 ...
- spring资源访问接口和资源加载接口
spring 资源访问接口 JDK提供的资源访问类,如java.net.URL.File等,不能很好地满足各种资源的访问需求,比如缺少从类路径或者Web容器的上下文中获取资源的操作类. 鉴于此,spr ...
- Expo大作战(三十九)--expo sdk api之 DocumentPicker,Contacts(获取手机联系人信息),Branch
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- spring cloud 配置文件application.yml和bootstrap.yml 的定位,区别和联系总算是有一点明白了
最近在启用springcloud配置中心server的东西,在整理属性资源的时候,突然发现:用了这么久的springboot,为什么会配置两个属性文件同时存在(application.yml/prop ...
- 【HANA系列】SAP HANA XS使用服务器JavaScript Libraries详解
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA XS使用服务器 ...
- Linux 查看本机串口方法
最近在了解嵌入式方面的知识,就随笔记录一下: 查看Linux本机串口: 1.查看串口是否可用 可以对串口发送数据比如对com1口,echo /dev/ttyS02.查看串口名称使用 ls -l /de ...
- ES6 入门
1.简介 ECMAScript 6.0 是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了.它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序, ...
- creo5.0安装教程(图文详解)
PTC公司最近发布了Creo 5.0正式版 ,作为最具其革命性的新一代产品设计软件,其所提供专业的二维和三维设计设计,能帮助企业和公司进行产品生命周期管理(PLM)和制定服务管理解决方案.Creo5. ...
- React路由 + 绝对路径引用
路由: 哈希路由(在url地址后加 #name) // 实现页面监听 window.onhashchange = function(){ console.log(‘hash:’,window.lo ...
- Redis String类型的API使用
package com.daxin.jedis_datastructure; import org.junit.After; import org.junit.Before; import org.j ...