洛谷P4016 负载平衡问题(最小费用最大流)
时间:2022-05-07
本文章向大家介绍洛谷P4016 负载平衡问题(最小费用最大流),主要内容包括题目描述、输入输出格式、输入输出样例、说明、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
题目描述
GG 公司有 nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 nn 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。
输入输出格式
输入格式:
文件的第 11 行中有 11 个正整数 nn ,表示有 nn 个仓库。
第 22 行中有 nn 个正整数,表示 nn 个仓库的库存量。
输出格式:
输出最少搬运量。
输入输出样例
输入样例#1:
5
17 9 14 16 4
输出样例#1:
11
说明
1 leq n leq 1001≤n≤100
昨天老师讲课的时候总在冥冥之中感觉这题貌似做过,貌似可以用贪心水过去,看了题解发现的确可以用贪心水QWQ....
网络流做法
其实很简单,只是我太菜想的太复杂了QWQ...
从S向每个点连容量为库存量,费用为0的边
从每个点向T连容量为平均库存量,费用为0的边
在相邻两个点之间连容量为INF,费用为1的边
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define AddEdge(x,y,z,f) add_edge(x,y,z,f),add_edge(y,x,-z,0)
using namespace std;
const int INF=1e8+10;
const int MAXN=1e4+10;
int N,M,S,T;
int C[MAXN][MAXN];
struct node
{
int u,v,w,f,nxt;
}edge[MAXN];
int head[MAXN],num=2;
inline void add_edge(int x,int y,int z,int f)
{
edge[num].u=x;
edge[num].v=y;
edge[num].w=z;
edge[num].f=f;
edge[num].nxt=head[x];
head[x]=num++;
}
int dis[MAXN],vis[MAXN],Pre[MAXN];
bool SPFA()
{
memset(dis,0xf,sizeof(dis));
memset(vis,0,sizeof(vis));
queue<int>q;
q.push(S);
dis[S]=0;
while(q.size()!=0)
{
int p=q.front();q.pop();
vis[p]=0;
for(int i=head[p];i!=-1;i=edge[i].nxt)
{
if(edge[i].f&&dis[edge[i].v]>dis[p]+edge[i].w)
{
dis[edge[i].v]=dis[p]+edge[i].w;
Pre[edge[i].v]=i;
if(!vis[edge[i].v])
vis[edge[i].v]=1,q.push(edge[i].v);
}
}
}
return dis[T]<INF;
}
int F()
{
int nowflow=INF;
for(int now=T;now!=S;now=edge[Pre[now]].u)
nowflow=min(nowflow,edge[Pre[now]].f);
for(int now=T;now!=S;now=edge[Pre[now]].u)
edge[Pre[now]].f-=nowflow,
edge[Pre[now]^1].f+=nowflow;
return nowflow*dis[T];
}
void MCMF()
{
int ans=0;
while(SPFA())
ans+=F();
printf("%dn",abs(ans));
}
int pre(int i)
{
if(i!=1) return i-1;
else return N;
}
int nxt(int i)
{
if(i!=N) return i+1;
else return 1;
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#endif
memset(head,-1,sizeof(head));
scanf("%d",&N);
int tot=0;
S=0,T=N+1;
for(int i=1;i<=N;i++)
{
int x;scanf("%d",&x);
AddEdge(S,i,0,x);
tot+=x;
}
tot=tot/N;
for(int i=1;i<=N;i++)
AddEdge(i,T,0,tot);
for(int i=1;i<=N;i++)
{
AddEdge(i,pre(i),1,INF);
AddEdge(i,nxt(i),1,INF);
}
MCMF();
return 0;
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 1小时实战入门小程序开发,历史上的今天案例讲解
- 小程序实现全屏幕高斯模糊背景图
- 小程序顶部导航栏,可滑动,可动态选中放大
- 小程序不同页面的异步回调,callback和promise的使用讲解
- java入门019~springboot批量导入excel数据到mysql
- Java点餐系统和点餐小程序新加微信消息推送功能
- Java点餐系统和点餐小程序新加排号等位功能
- IDEA上给文件添加姓名,日期,版本号
- matlab机器人工具箱安装与卸载
- 浅谈Linux下修改/设置环境变量JAVA_HOME的方法
- Linux服务器配置多个svn仓库流程详解
- linux服务器显卡崩溃解决方案
- LINUX查看进程的4种方法(小结)
- Linux下的多线程编程实例解析
- CentOS使用expect批量远程执行脚本和命令