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 ...
随机推荐
- python中strip()方法学习笔记
Python strip() 方法用于移除字符串头尾指定的字符(默认为空格). 当使用strip('xxx'),只要字符串头尾有"xxx"中的一个,就会去掉,而不是符合字符串''x ...
- C# 异步编程3 TPL Task 异步程序开发
.Net在Framework4.0中增加了任务并行库,对开发人员来说利用多核多线程CPU环境变得更加简单,TPL正符合我们本系列的技术需求.因TPL涉及内容较多,且本系列文章为异步程序开发,所以本文并 ...
- [20170705]理解linux su命令.txt
[20170705]理解linux su命令.txt --//我一般在维护时经常使用root用户登录,然后su - oracle 转到其他用户操作--//一般都加入 - 参数.这个已经成了条件反射.. ...
- python第四天 三级菜单新思路
今天是一个坎,在做三级菜单时卡住了,因为想要简洁的代码,就要用到递归函数,卡的不要不要的!不过最后在同学老师的提点帮助下,还是解决了! 2017-5-10发现之前的代码有BUG今天 修改了! 作业要求 ...
- 什么是ORM?为啥要是用ORM?
了解orm,先了解以下概念: 什么是“持久化” 持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的数据存储在关系型的数据库中 ...
- Linux 小知识翻译 - 「桌面环境」
这次聊聊桌面环境. 上次聊了 X Window System 相关的内容,虽然令人意外,但X Window System 和桌面环境不是一回事.请大家稍微考虑一下. X Window System 是 ...
- 阿里八八β阶段Scrum(4/5)
今日进度 黄梅玲: 图表绘制与实时更新的完成 刘晓: 数据分析表格部分生成完成 张岳: 初步完成简易的桌面控件 陈裕鹏: 事件添加TAG标签的功能完成,此外信息抽取算法也基本完成并PULL,但与项目产 ...
- Linux Java 环境配置及内置tomcat部署
tar zxvf jdk-8u101-linux-x64.tar.gz vi /etc/profile JAVA_HOME=/home/puma/jdk1.8.0_111JAVA_BIN=/home/ ...
- 用Promise解决多个异步Ajax请求导致的代码嵌套问题【转】
问题 前端小同学在做页面的时候,犯了个常见的错误:把多个Ajax请求顺序着写下来了,而后面的请求,对前面请求的返回结果,是有依赖的.如下面的代码所示: var someData; $.ajax({ u ...
- VC++界面编程之--仿Facebook透明登录窗体
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/renstarone/article/details/27642765 1. 开发工具:VC++ DU ...