传说中的网络流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. PopupWindow 弹出时背景变暗

    下面的PopupWindow  的高是相对于屏幕高设计,宽是获取的某一个控件的宽设置,位置位于某控件的上方,红色部分是设置弹出时屏幕变暗的. //设置contentView View contentV ...

  2. Hexo + Github 个人博客设置以及优化

    原文地址: Hexo + Github 个人博客设置以及优化 一.博客设置 分类.标签云.关于等页面 在站点目录下分别执行: hexo new page "categories" ...

  3. Cookie的HttpOnly、secure、domain属性

    Cookie主要属性 Cookie主要属性: path domain max-age expires:是expires的补充,现阶段有兼容性问题:IE低版本不支持,所以一般不单独使用 secure h ...

  4. 进程管理-PV操作

    1.临界资源:诸进程需要互斥方式对其进行共享的资源. 2.临界区:每个进程中访问临界资源的那段代码. 3.信号量:一种特殊的变量.

  5. C# MD5 加密

    public static string MD5Encrypt(string clearText) { string result = string.Empty; byte[] byteArray = ...

  6. Django学习---py3下的富文本编辑器的使用

    背景说明: Ueditor HTML编辑器是百度开源的HTML编辑器,但是在Python3下调用报错,找不到widgets模块,经查发现,DjangoUeditor是基于Python 2.7的,对Py ...

  7. centos7搭建SVN+Apache+IF.svnadmin支持https实现web管理SVN

    阅读目录 1. 介绍 2. 软件准备 3. 建立SVN Server仓库 4. 配置安装PHP&IF.SVNadmin 5. 启动服务 1.介绍 公司最近想把Windows server平台的 ...

  8. godaddy.com 都转到 www.dnspod.cn

    我们在godaddy上注册了域名,但因为godaddy对域名解析的诸多限制和缓慢. 所以必需把域名服务器更改为dnspod上,然后再在dnspod上做A记录,CNAME等设置都很方便.

  9. linux内网IP如果判断出网IP地址

    [root@jumpserver ~]# curl https://ip.cn当前 IP: 162.14.210.16 来自: 河南省郑州市 xx网络

  10. mysql ANSI_QUOTES 这个sql_mode的作用(字段可以使用双引号)

    首先sql_mode用于mysql的行为,sql_mode的多个值之间用','分隔: 如果想使用双引号就这样做: 1. 修改/etc/my.cnf文件 ,  双引号模式是ANSI_QUOTES 或   ...