传说中的网络流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 负载平衡问题的更多相关文章

  1. 洛谷 P4016负载平衡问题【费用流】题解+AC代码

    洛谷 P4016负载平衡问题 P4014 分配问题[费用流]题解+AC代码 负载平衡问题 题目描述 GG 公司有n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n ...

  2. P4016 负载平衡问题 网络流

    P4016 负载平衡问题 题目描述 GG 公司有 nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 nn个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运 ...

  3. P4016 负载平衡问题(最小费用最大流)

    P4016 负载平衡问题 题目描述 GG 公司有 nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 nn 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬 ...

  4. P4016 负载平衡问题 网络流重温

    P4016 负载平衡问题 这个题目现在第二次做,感觉没有这么简单,可能是我太久没有写这种题目了,基本上都忘记了,所以我连这个是费用流都没有看出来. 有点小伤心,知道是费用流之后,我居然还拆点了. 这个 ...

  5. 洛谷P4016负载平衡

    题目 负载平衡问题是一个比较经典的网络流问题,但是该问题还有一个数学贪心法. 所以做这个题前,其实可以做一下均分纸牌问题. 均分纸牌问题 均分纸牌问题可以说是作为贪心的入门题. 做法 首先我们应当把原 ...

  6. (洛谷P2512||bzoj1045) [HAOI2008]糖果传递 || 洛谷P4016 负载平衡问题 || UVA11300 Spreading the Wealth || (洛谷P3156||bzoj3293) [CQOI2011]分金币

    bzoj1045 洛谷P4016 洛谷P2512 bzoj3293 洛谷P3156 题解:https://www.luogu.org/blog/LittleRewriter/solution-p251 ...

  7. 洛谷 [P4016] 负载平衡问题

    贪心做法 第一眼看见觉得和均分纸牌差不多,然而因为这是环形的,并不能用均分纸牌的方法做,但是均分纸牌的思想仍然适用 首先我们假设平均数为sum1. 那么对于第1个人,我们假设他给第N个人K个糖果, 第 ...

  8. 『题解』洛谷P4016 负载平衡问题

    title: categories: tags: - mathjax: true --- Problem Portal Portal1:Luogu Portal2: LibreOJ Descripti ...

  9. P2512 [HAOI2008]糖果传递&&P3156 [CQOI2011]分金币&&P4016 负载平衡问题

    P2512 [HAOI2008]糖果传递 第一步,当然是把数据减去平均数,然后我们可以得出一串正负不等的数列 我们用sum数组存该数列的前缀和.注意sum[ n ]=0 假设为链,那么可以得出答案为a ...

随机推荐

  1. LDA背景资料

    [https://zhuanlan.zhihu.com/p/30226687] LDA模型的前世今生 在文本挖掘中,有一项重要的工作就是分析和挖掘出文本中隐含的结构信息,而不依赖任何提前标注的信息.L ...

  2. SolrCloud集群搭建(基于zookeeper)

    1. 环境准备 1.1 三台Linux机器,x64系统 1.2 jdk1.8 1.3 Solr5.5 2. 安装zookeeper集群 2.1 分别在三台机器上创建目录 mkdir /usr/hdp/ ...

  3. TensorFlow实现梯度下降

    # -*- coding: utf-8 -*- """ Created on Mon Oct 15 17:38:39 2018 @author: zhen "& ...

  4. 06-OpenLDAP密码策略

    阅读视图 openldap密码策略 OpenLDAP服务端定制密码策略 客户端策划策略实例 定义用户第一次登录就修改密码 问题排查手册 重点推荐官方文档 备注:本文依然承接系列文. 1. openld ...

  5. vue-cli在控制台创建vue项目时乱码的问题

    新装的win10系统,使用vue-cli在控制台创建项目时出现乱码,请问如何处理? 解决: 打开cmd,在控制台输入CHCP 65001,按回车键即可将编码格式设成utf-8,再创建就不会乱码了. 执 ...

  6. 2.2Python数据处理篇之---math模块的数学函数

    目录 目录 前言 (一)一览表 1.基本函数 2.对数函数 3.三角函数 4.角度的切换 5.双曲函数 6.math定义的常数 (二)实例 目录 前言 math模块是基础的python数学函数模块,是 ...

  7. Python 列表(List)包含的函数与方法

    Python列表函数&方法 Python包含以下函数: 序号 函数 1 cmp(list1, list2)比较两个列表的元素 2 len(list)列表元素个数 3 max(list)返回列表 ...

  8. 【转】handbrake使用教程

           原文地址http://tieba.baidu.com/p/2399590151?pn=1         现在的很多压制教程基本都是使用megui或者mediacoder的,这两个软件使 ...

  9. Html body的滚动条禁止与启用

    在写一个在页面中,经验证用户没有登录或session失效时候弹出登录框禁止页面滚动用到今天搞了一个功能,上下左右居中,模仿QQ空间里的样式,把横向和纵向滚动条禁止掉代码如下:<script ty ...

  10. Django之ORM查询

    ORM 映射关系: 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象图书管理系统的增删改查:代码如下:views ...