这道题还是很好的.

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

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

我们可以将相邻点之间的流量建为无限大,单位费用设为 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:

#include<cstdio>              //好题
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=500;
const int INF=1000000+23666;
typedef long long ll;
int A[maxn];
int s,t,n;
struct Edge{
int from,to,cap,cost;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),cost(f){}
};
struct MCMF{
vector<Edge>edges;
vector<int>G[maxn];
int d[maxn],inq[maxn],a[maxn],flow2[maxn];
queue<int>Q;
ll ans=0;
int flow=0;
void addedge(int u,int v,int c,int f){
edges.push_back(Edge(u,v,c,f)); //正向弧
edges.push_back(Edge(v,u,0,-f)); //反向弧
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
int SPFA(){
for(int i=0;i<=n;++i)d[i]=INF,flow2[i]=INF;
memset(inq,0,sizeof(inq));int f=INF;
d[s]=0,inq[s]=1;Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();inq[u]=0;
int sz=G[u].size();
for(int i=0;i<sz;++i){
Edge e=edges[G[u][i]];
if(e.cap>0&&d[e.to]>d[u]+e.cost){
a[e.to]=G[u][i];
d[e.to]=d[u]+e.cost;
flow2[e.to]=min(flow2[u],e.cap);
if(!inq[e.to]){inq[e.to]=1;Q.push(e.to);}
}
}
}
if(d[t]==INF)return 0;
f=flow2[t];
flow+=f;
int u=edges[a[t]].from;
edges[a[t]].cap-=f;
edges[a[t]^1].cap+=f;
while(u!=s){
edges[a[u]].cap-=f;
edges[a[u]^1].cap+=f;
u=edges[a[u]].from;
}
ans+=(ll)(d[t]*f);
return 1;
}
ll maxflow(){
while(SPFA());
return ans;
}
// ll getcost(){return ans;}
}op;
int main()
{
int N;scanf("%d",&N);
s=0,t=N+1,n=N+1;
int sum=0,ave;
for(int i=1;i<=N;++i){
int a;scanf("%d",&a);
A[i]=a;
sum+=a;
}
ave=sum/N;
for(int i=1;i<=N;++i)
{
int a=A[i]-ave;
if(a>0)op.addedge(s,i,a,0);
if(a<0)op.addedge(i,t,-a,0);
}
for(int i=2;i<N;++i)
{
op.addedge(i,i-1,INF,1);
op.addedge(i,i+1,INF,1);
}
op.addedge(1,2,INF,1);
op.addedge(1,N,INF,1);
op.addedge(N,N-1,INF,1);
op.addedge(N,1,INF,1);
printf("%lld",op.maxflow());
return 0;
}

  

洛谷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. Date.getTime() 结果为 NaN

    yyyy-MM-dd 格式的时间,部分浏览器环境下转换为 Date 对象后调用 getTime() 方法的结果为 NaN. 需要将 - 替换为 / var dateStr = '2019-01-01' ...

  2. 数据库自动备份压缩脚本(备份最近七天,七天之前自动删除,只保留rar文件)

    把下面脚本添加到服务器计划任务中去,设置为每天执行即可,文件备份路径即为脚本所在路径,必须安装压缩文件 @echo offrem 计算指定天数之前的日期,用于后面删除指定天数的数据set DaysAg ...

  3. C++ 简单内存泄漏检测方法

    遇到个bug,MFC程序异常退出,debug模式下输出 Detected memory leaks! Dumping objects -> {366566} normal block at 0x ...

  4. elasticsearch集群安全重启节点

    es2.x 关闭集群的动态分片:(动态分片开启状态如果节点宕机了,会导致集群重新分配数据进行数据转移,会导致节点直接大量传输数据)curl -XPUT 'http://192.168.248.193: ...

  5. Side effect (computer science)

    In computer science, a function or expression is said to have a side effect if it modifies some stat ...

  6. mac 调整Launchpad行列数目

    Mac调整Launchpad  行数和列数 开打Terminal终端依次输入以下三句: <1> 改变行数:defaults write com.apple.dock springboard ...

  7. Ibatis在运行期得到可执行到sql

    环境:oracle-11g ,ibatis-2.0 ,java-1.7 最近因为有个需要是在程序中得到ibatis到sql字符串,即通过以下的ibatis配置得到sql语句 <select id ...

  8. Extjs获取input值的几种方法

    记录一下: ExtJs获取文本框中值的几种方式 EXTHTML 1.Html文本框 如: 获取值的方式为: var tValue = Ext.getDom('test').value; 或者 var ...

  9. HDU1027 Ignatius and the Princess II( 逆康托展开 )

    链接:传送门 题意:给出一个 n ,求 1 - n 全排列的第 m 个排列情况 思路:经典逆康托展开,需要注意的时要在原来逆康托展开的模板上改动一些地方. 分析:已知 1 <= M <= ...

  10. [luogu 2568] GCD (欧拉函数)

    题目描述 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 输入输出格式 输入格式: 一个整数N 输出格式: 答案 输入样例#1: 4 输出样例#1: 4 ...