UOJ #455.【UER #8】雪灾与外卖 堆模拟费用流
题意
有n个人和m家商店,每个人都要买一道菜。第i个人的坐标是a[i],第j家商店的坐标是y[i],有c[i]道菜且每道菜价格为w[i],每个人还要花费其到商店距离的路费,问最小花费。
n,m≤105,a[i],y[i],c[i],w[i]≤109n,m\le10^5,a[i],y[i],c[i],w[i]\le10^9n,m≤105,a[i],y[i],c[i],w[i]≤109
分析
显然可以费用流做,但跑不过。
考虑把商店和人放到一起按坐标排序,然后从左往右扫,然后不断维护当前的最优解。但当前最优解可能并不是全局最优解,所以还要维护撤销操作。
更具体的讲,对人和商店分别用一个堆来维护,堆中权值表示我要将当前商店或人空置出来并与新加入的人或商店匹配需要付出的最小代价。当新加入一个人时就选择一个最优的商店匹配;新加入一个商店时则尽可能的撤销之前的操作并使答案变得更优。
再加一个小优化,把费用相同的撤销操作放到一起,复杂度就是正确的了。
时间复杂度O(nlogn)O(nlogn)O(nlogn)。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>typedef long long LL;const int N=100005;
const LL inf=(LL)1e15;int n,m;
LL a[N],y[N],w[N],c[N],ans;
struct data
{LL w,s;bool operator < (const data &t) const {return w>t.w;}
};
std::priority_queue<data> A,B;void ins1(LL x)
{LL p=B.top().w,s=B.top().s;B.pop();ans+=x+p;A.push((data){-(x+p)-x,1});if (s>1) B.push((data){p,s-1});
}void ins2(LL y,LL w,LL c)
{LL k=0;while (!A.empty()&&k<c&&A.top().w+y+w<0){LL p=A.top().w,s=A.top().s,f=std::min(c-k,s);A.pop();s-=f;k+=f;ans+=f*(p+y+w);if (s) A.push((data){p,s});B.push((data){-(p+y+w)+w-y,f});}if (k) A.push((data){-y-w,k});if (k<c) B.push((data){-y+w,c-k});
}int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++) scanf("%lld",&a[i]);LL tot=0;for (int i=1;i<=m;i++) scanf("%lld%lld%lld",&y[i],&w[i],&c[i]),tot+=c[i];if (tot<n) {puts("-1");return 0;}y[0]=-inf;c[0]=inf;int i=1,j=0;while (i<=n&&j<=m){if (a[i]<=y[j]) ins1(a[i]),i++;else ins2(y[j],w[j],c[j]),j++;}while (i<=n) ins1(a[i]),i++;while (j<=m) ins2(y[j],w[j],c[j]),j++;printf("%lld\n",ans);return 0;
}
UOJ #455.【UER #8】雪灾与外卖 堆模拟费用流相关推荐
- [UOJ455][UER #8]雪灾与外卖——堆+模拟费用流
题目链接: [UOJ455]雪灾与外卖 题目描述:有$n$个送餐员(坐标为$x_{i}$)及$m$个餐厅(坐标为$y_{i}$,权值为$w_{i}$),每个送餐员需要前往一个餐厅,每个餐厅只能容纳$c ...
- UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
题目链接 http://uoj.ac/contest/47/problem/455 题解 模拟费用流,一个非常神奇的东西. 本题即为WC2019 laofu的讲课中的Problem 8,经典的老鼠进洞 ...
- 【贪心+堆/模拟费用流增广】BZOJ4946 [NOI2017]蔬菜
一道思路很好的题,因为篇幅太长赶时间,以下多数转自这里 [题目] 定义了一种蔬菜为: a i , s i , c i , x i a_i,s_i,c_i,x_i ai,si,ci,xi,有 n ...
- BZOJ1150[CTSC2007]数据备份Backup——模拟费用流+堆+链表
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游 ...
- 1147 Heaps (30 分)【难度: 一般 / 知识点: 堆 模拟 】
https://pintia.cn/problem-sets/994805342720868352/problems/994805342821531648 直接按照堆模拟即可,如果对于每一个根来说,它 ...
- 数据结构之堆(Heap),堆的相关操作,用堆模拟优先级队列
目录 堆的概念 堆的存储方式 堆的相关操作 堆的向下调整. 堆的创建 堆的插入和向上调整 堆的删除 用堆模拟优先级队列 堆的概念 堆是逻辑结构为二叉树存储结构为数组数组的一种数据结构,为什么这么说呢? ...
- 堆糖瀑布流完整解决方案(jQuery)
2010年堆糖创办以来,网站界面经历过3-5次重大改版,logo也曾更换过两次,早期蓝红相间三个圈的logo恐怕很少有人记得了.与此同时,前端 js 框架也在默默的更新换代.最早堆糖上线时,js 采用 ...
- 【UOJ#389】【UNR#3】白鸽(欧拉回路,费用流)
[UOJ#389][UNR#3]白鸽(欧拉回路,费用流) 题面 UOJ 题解 首先第一问就是判断是否存在一条合法的欧拉回路,这个拿度数和连通性判断一下就行了. 第二问判断转的圈数,显然我们只需要考虑顺 ...
- 【UOJ455】【UER #8】雪灾与外卖
[题目链接] 点击打开链接 [思路要点] 首先判断是否无解,以下讨论默认问题有解. 令 ∞\infty∞ 为一个足够大的数,对于送餐员 XiX_iXi ,在 Xi−∞X_i-\inftyXi−∞ ...
最新文章
- 芯片、模组、开发板的区别与联系-结合ESP32浅谈(转载)
- 渐进式Web应用程序的深入概述
- Linux futex 快速同步互斥机制简介
- Deep Learning(深度学习)学习笔记整理系列
- 如何应对数据库CPU打满?最优解在这里...
- Python模块学习
- rpm yum 删除mysql
- Java的世界如此美妙
- 百度谷歌雅虎搜狗提交链接入口
- R语言本地安装包教程
- 使用mimikatz抓取windows管理员密码
- 2017年最牛逼的分类Android项目源码免费一次性打包下载!
- VS2010使用c++、gSOAP创建WebService 图文教程
- 吉他 c大调第一把位
- GRUB4DOS使用大全
- mysql select from user_select * from user 这条 SQL 语句,背后藏着哪些不可告人的秘密?...
- Ansible Inventory内置参数
- 乐观中谨慎 招聘调薪现贫富差距
- ReID中PCB模型输出维度_搞定PCB信号完整性,只需9步!都可以学会
- 【agv搬运机器人价格大全】agv智能搬运机器人多少钱-厂家揭晓