【UER #8】雪灾与外卖
题解:
这个东西的模型是个费用流
但是直接跑费用流能拿到5分的高分
$(nm)*(nm)*log{nm}$
考虑优化一下建图
我们可以不用对每个店和人都连边
而是对人和店都连一条链
然后对每个人连店刚好比它大和比它小的两个点
这样有25分
我们容易发现每个店的区间都是连续并且递增的
于是可以dp
单调队列优化之后就可以有50分
再之后的做法就比较神奇
考虑先将每个店容量拆成1
我们将店和人按照坐标排序
由于每个人都是要匹配的,所以我们可以直接将它和前面的匹配(如果没有看成和无限远处匹配)
然后当我们加入一家店时,我们看一看有没有人换成和它匹配更优,没有就直接插入
具体如何实现呢
我们对店和人分别维护一个堆
一个人去匹配店的时候,产生的代价为$x+y$ (x为坐标,y为店堆顶)
匹配完后我们要支持人的反悔操作(容易yy店是不可能反悔的)
也就是往人的堆里插入$-(x+y)-x$
一个店去匹配人的时候,产生的代价为$x+y+w$(y为坐标,w为花费,x为人堆顶)
匹配完后要支持人和店的反悔
人的反悔是$-(y+x坐标+w)-x坐标$=$-y-w$
店的反悔我们可以通过推一下反悔后的式子(注意反悔时我们要将它现在匹配的那个人匹配的店变回之前匹配的店)$-x-2*y$
刚开始在店1 人1 店2 人2 店3 店4(假设店对两个人的花费都是从大到小)
这个例子上纠结了一下(人和店1的匹配被弹栈了之后怎么办)
后来发现 如果出现店1 人1 店2的话(且店2比店1优) 一定不存在一种时候可以直接从店1 人1的匹配变成人1和其他店
因为如果后面有店一定先让人2匹配,而一旦人2匹配了人1就匹配了店2
然后考虑一下满分做法
没有了ci的限制 我们就不能拆了 对于人的操作 时间复杂度是对的
而对于物品的操作,时间复杂度的瓶颈在于对每个人可能每个位置的店都要算一次
我们发现对于同一个位置的店的人的反悔操作,我们可以放在一起,都只跟店有关
而对于多余的店,也可以放在一起
因为每次操作只能使块数增加1 所以最多减少n+m次
复杂度$(n+m)log$
我是照着这份代码看懂的。。
#include<bits/stdc++.h>
using namespace std;
#define FOR(a,b,c) for(int a=(b),a##_end__=(c);a<a##_end__;++a)
#define INF 0x3f3f3f3f3f3f3f3fLL
template<class T>inline bool chkmin(T&a,T const&b){return b<a?a=b,true:false;}
template<class T>inline bool chkmax(T&a,T const&b){return a<b?a=b,true:false;}
const int M=;
priority_queue<pair<long long,int>,vector<pair<long long,int>>,greater<pair<long long,int>>>A,B;
int X[M],Y[M],W[M],C[M];
long long ans,cnt;
int n,m;
void push_x(long long x){
long long y;
if(B.empty()) y=INF;
else y=B.top().first;
ans+=x+y;
A.push(make_pair(-*x-y,));
if(!B.empty()){
int f=B.top().second;
B.pop();
if(<f) B.push(make_pair(y,f-));
}
}
void push_y(long long y,long long w,int c){
int m=;
while(c!=m and !A.empty() and y+w+A.top().first<){
long long x=A.top().first;
int f=A.top().second,t=min(c-m,f);
ans+=t*(x+y+w);
A.pop();
if(t!=f) A.push(make_pair(x,f-t));
B.push(make_pair(-x-*y,t));
m+=t;
}
if(m) A.push(make_pair(-y-w,m));
if(c!=m) B.push(make_pair(-y+w,c-m));
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
FOR(i,,n) scanf("%d",X+i);
FOR(i,,m) scanf("%d%d%d",Y+i,W+i,C+i);
FOR(i,,m) cnt+=C[i];
if(cnt<n) return puts("-1"),;
int i=,j=;
while(i<n and j<m){
if(X[i]<Y[j]) push_x(X[i]),++i;
else push_y(Y[j],W[j],C[j]),++j;
}
while(i<n) push_x(X[i]),++i;
while(j<m) push_y(Y[j],W[j],C[j]),++j;
printf("%lld\n",ans);
return ;
}
【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,经典的老鼠进洞 ...
- uoj455 【UER #8】雪灾与外卖
http://uoj.ac/problem/455 题解: https://blog.csdn.net/litble/article/details/88410435 https://www.mina ...
- 题解-UOJ 455雪灾与外卖
Problem \(\mathrm{UOJ~455}\) 题意概要:一根数轴上有 \(n\) 只老鼠与 \(m\) 个洞,每个洞有费用与容量限制,要求每只老鼠要进一个洞且每个洞的老鼠不超过自身的容量限 ...
- NOIWC2019 冬眠记
冬眠 由于THUWC考太差了没啥心情做事…… Day -1 报到日前一天晚上去看了看宿舍表,发现周围全是集训队,隔壁就是栋爷.高队和lca,再隔壁是zzq和wxh……吓傻了(本校buff这么好吗) D ...
- [codevs 2800]送外卖
题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上.n个不同的客户分别在1~n个编号的城市中.送外卖的从0号城市出发,然后n个城市都要走一 ...
- codevs2800 送外卖
题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上.n个不同的客户分别在1~n个编号的城市中.送外卖的从0号城市出发,然后n个城市都要走一 ...
- 项目vue2.0仿外卖APP(一)
最近用vue.js做一个仿饿了么外卖APP的项目,现在也把流程啊什么的暂时先整理一下在这个博客上面. 当然,这个过程会有点长,不过确实能学到很多东西. 话不多说,马上开始吧. 1.项目介绍 选用当前最 ...
- 【CodeVS2800】 送外卖 最短路+状压DP
首先求出各点之间的最短路,floyed即可,注意是0-n. 然后考虑状压,f[i][j]表示状态为i时访问j点时的最短路和,1表示访问,0表示未访问,然后第j个点所在的位置就是(1<<j) ...
随机推荐
- 江西财经大学第二届程序设计竞赛同步赛 H大时钟 (扩展欧几里得)
链接:https://ac.nowcoder.com/acm/contest/635/H来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- Python学习day17 迭代器&生成器
迭代器&生成器 1. 迭代器 1.1 迭代器 迭代:迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代" 迭代器:帮助对某种对象 ...
- [ZJOI2019]线段树(线段树)
看到这题,首先想到将求和转期望,即每次操作进行概率为1/2,求节点打标记概率. 首先对于每次区间修改操作,对节点进行分类: 1.这个点和其父亲都和修改区间无交,这种情况可以无视. 2.这个点和修改区间 ...
- docker容器网络
1.我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式: · host模式,使用--net=host指定 · containe ...
- MAC上有哪些优秀的日常软件| 入门级Mac OS 用户必备软件
本文整理的网友反馈的MAC上有哪些优秀的日常软件+入门级Mac OS 用户必备软件,感兴趣的朋友可以看看,下载下来试用一样便知实不实用.如有更好的推荐,欢迎留言. MAC上有哪些优秀的日常软件 Tim ...
- Java基础--面向对象编程3(继承)
1.继承的作用 为了提取两个类中公共的代码,可以使用继承抽取重复性的代码到一个公共类中. 这个公共的类称为父类(super class),继承于父类的类称为子类(sub class). 2.java继 ...
- linux批量压缩当前目录中文件后,删除原文件
linux批量压缩当前目录中文件后,删除原文件 for i in `ls|awk -F " " '{print $NF}'`; do tar -zcvf $i.tar.gz $i ...
- CentOS 7 安装docker (图文)
一定要用root账号登录系统,打开终端/或远程工具(如xshell)登录系统 检查是否已经安装命令 rpm –qa|grep docker 出现如上说明已安装 也可用命令docker -v (如 ...
- 使用Vim-plug作为Vim 插件管理器
ref: https://www.cnblogs.com/jiftle/p/6918157.html - vundle是一款老款的插件管理工具- vim-plug相对较新,特点是支持异步加载,相比vu ...
- macbook配置xdebug+vscode
1.从xdebug官网下载xdebug 地址:https://xdebug.org/index.php,如果你不知道你要下载哪个版本的话可以下载它建议的版本.使用方法是在 https://xdebug ...