这道题还是很好的.

考察了选手对网络流的理解.

首先,任意两个相邻点之间的运货量时没有限制的.

我们可以将相邻点之间的流量建为无限大,单位费用设为 1,代表运输一个货物需耗费一个代价.

由于题目要求最后所有人的货物量都相同,则说明每个人在最后拥有的货物量一定是总货物量的平均数,我们设为 $w$.

考虑一个点开始是的货物量为 $a$,则讨论两种情况.

1. a > w,则说明 $a$ 需要向周围的站点送出 $a-w$ 个货物以达到供需平衡. 我们从源点向该点流进 (a-w) 的流量,费用为 0

2. a < w,则说明该点需要得到 $w - a$ 个货物的补给,那么就让该点向汇点流出 (w-a) 的流量,费用仍然为 0.

我们思考一下,为什么这样是对的 ?

我们发现,所有点 (a-w) 之和一定为 0. (因为总量是守恒的)

首先,考虑第一种情况.

由于一个点被源点流进了 $a-w$ 的流量,那么该点一定会流出 $a-w$ 的流量,那么该点会至少贡献 $a-w$ 的花费.

由于流量是可以流满的,所以该做法就是正确的

Code:

  1. #include<cstdio> //好题
  2. #include<algorithm>
  3. #include<vector>
  4. #include<cstring>
  5. #include<queue>
  6. using namespace std;
  7. const int maxn=500;
  8. const int INF=1000000+23666;
  9. typedef long long ll;
  10. int A[maxn];
  11. int s,t,n;
  12. struct Edge{
  13. int from,to,cap,cost;
  14. Edge(int u,int v,int c,int f):from(u),to(v),cap(c),cost(f){}
  15. };
  16. struct MCMF{
  17. vector<Edge>edges;
  18. vector<int>G[maxn];
  19. int d[maxn],inq[maxn],a[maxn],flow2[maxn];
  20. queue<int>Q;
  21. ll ans=0;
  22. int flow=0;
  23. void addedge(int u,int v,int c,int f){
  24. edges.push_back(Edge(u,v,c,f)); //正向弧
  25. edges.push_back(Edge(v,u,0,-f)); //反向弧
  26. int m=edges.size();
  27. G[u].push_back(m-2);
  28. G[v].push_back(m-1);
  29. }
  30. int SPFA(){
  31. for(int i=0;i<=n;++i)d[i]=INF,flow2[i]=INF;
  32. memset(inq,0,sizeof(inq));int f=INF;
  33. d[s]=0,inq[s]=1;Q.push(s);
  34. while(!Q.empty()){
  35. int u=Q.front();Q.pop();inq[u]=0;
  36. int sz=G[u].size();
  37. for(int i=0;i<sz;++i){
  38. Edge e=edges[G[u][i]];
  39. if(e.cap>0&&d[e.to]>d[u]+e.cost){
  40. a[e.to]=G[u][i];
  41. d[e.to]=d[u]+e.cost;
  42. flow2[e.to]=min(flow2[u],e.cap);
  43. if(!inq[e.to]){inq[e.to]=1;Q.push(e.to);}
  44. }
  45. }
  46. }
  47. if(d[t]==INF)return 0;
  48. f=flow2[t];
  49. flow+=f;
  50. int u=edges[a[t]].from;
  51. edges[a[t]].cap-=f;
  52. edges[a[t]^1].cap+=f;
  53. while(u!=s){
  54. edges[a[u]].cap-=f;
  55. edges[a[u]^1].cap+=f;
  56. u=edges[a[u]].from;
  57. }
  58. ans+=(ll)(d[t]*f);
  59. return 1;
  60. }
  61. ll maxflow(){
  62. while(SPFA());
  63. return ans;
  64. }
  65. // ll getcost(){return ans;}
  66. }op;
  67. int main()
  68. {
  69. int N;scanf("%d",&N);
  70. s=0,t=N+1,n=N+1;
  71. int sum=0,ave;
  72. for(int i=1;i<=N;++i){
  73. int a;scanf("%d",&a);
  74. A[i]=a;
  75. sum+=a;
  76. }
  77. ave=sum/N;
  78. for(int i=1;i<=N;++i)
  79. {
  80. int a=A[i]-ave;
  81. if(a>0)op.addedge(s,i,a,0);
  82. if(a<0)op.addedge(i,t,-a,0);
  83. }
  84. for(int i=2;i<N;++i)
  85. {
  86. op.addedge(i,i-1,INF,1);
  87. op.addedge(i,i+1,INF,1);
  88. }
  89. op.addedge(1,2,INF,1);
  90. op.addedge(1,N,INF,1);
  91. op.addedge(N,N-1,INF,1);
  92. op.addedge(N,1,INF,1);
  93. printf("%lld",op.maxflow());
  94. return 0;
  95. }

  

洛谷P4016 负载平衡问题 费用流的更多相关文章

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

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

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

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

  3. 洛谷P4016负载平衡

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

  4. 洛谷P4016 负载平衡问题(费用流)

    传送门 嗯……完全不会……不过题解似乎讲的挺清楚…… 考虑一下,每一个仓库最终肯定都是平均数,所以数量大于平均数的可以往外运,小于平均数的要从别的地方运进来 考虑建一个超级源$S$和超级汇$T$,并把 ...

  5. 洛谷 P4016 负载平衡问题 【最小费用最大流】

    求出平均数sum,对于大于sum的点连接(s,i,a[i]-sum,0),表示这个点可以流出多余的部分,对于小于sum的点连接(i,t,sum-a[i],0)表示这个点可以接受少的部分,然后每个点向相 ...

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

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

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

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

  8. 洛谷P4016 负载平衡问题

    题目描述 G 公司有 n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入输出格式 输入格式: ...

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

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

随机推荐

  1. Hibernate框架学习(四)——事务

    一.回顾事务的概念http://www.cnblogs.com/cxq1126/p/8313600.html 1.特性ACID:原子性.一致性.隔离性.持久性 2.并发问题:脏读.不可重复读.幻|虚读 ...

  2. 页面加载通过javascript来修改控件属性

    function changeFormElementStatus(tagNames) {            var tagNameArr = tagNames.split("," ...

  3. 深入分析C++虚函数表

    C++中的虚函数(Virtual Function)是用来实现动态多态性的,指的是当基类指针指向其派生类实例时,可以用基类指针调用派生类中的成员函数.如果基类指针指向不同的派生类,则它调用同一个函数就 ...

  4. Lambda 表达式-即匿名函数

    拉姆达值(Lambda),希腊字母表示为Λ,指与真空的空间有关的能量或暗能量.   代表转换的常量.或者转换本身.   Lambda 表达式 Lambda 表达式”是一个匿名函数,可以包含表达式和语句 ...

  5. 注解实战aftersuite和beforesuite

    package com.course.testng;import org.testng.annotations.*; public class BasicAnnotation { //最基本的注解,用 ...

  6. 说说Shell在代码重构中的应用

    说说Shell在代码重构中的应用    出处信息 出处:http://blogread.cn/it/article/3426?f=wb 代码重构(Code refactoring)有时是很枯燥的,字符 ...

  7. elment表格分页

    项目的时候遇到了一个分页的bug,经过分析Element源码之后找到了问题所在,现在把这个问题及解决方法记录下来. 项目中要实现的功能是用户选择查看表格的时候在任意页面点击查询,得到结果之后要展示的页 ...

  8. laravel报错:Unable to detect application namespace.

    使用报错:Unable to detect application namespace. 是conposer.json格式不对

  9. 开放个人电脑端口[Windows]

    先打开控制面板

  10. JAVA面向对象编程深入理解图