【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)
【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)
考虑最终答案的构成,一定是由很多飞行+一些上升+一些下降构成。
由于在任何一个点上升或者下降代价是一样的,所以:
对于上升操作来说,只要保证前面飞行合法就不需要上升。当且仅当我飞不过去了才上升。
对于下降操作来说,只要我不会越过目标点就不需要下降。当且仅当我会越过目标点才下降。
也就是说,上升和下降操作是不需要手动进行决策的,不存在一种更优解使得这种解通过提前上升或者下降来使得时间花费缩短。因为假设存在一种“更优解”,可以通过尽量延后上升操作而构造出一组满足上面两个原则的同样优的解。
所以对于每个点,记录一个\(Height\)表示当前高度和\(dis\)表示花费时间直接Dijkstra即可。
分析一下复杂度,不管如何代价都是正的,所以同样是\(O(n \log m)\)
在读入的时候顺便删掉不合法边...
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1e5+5;
const ll inf=1e18;
typedef pair<ll,int> P;
typedef priority_queue<P,vector<P>,greater<P> > Qp;
Qp q;
ll d[maxn];
int Height[maxn];
pair<int,pair<int,int> > last[maxn];
vector< pair<int,int> > e[maxn];
int h[maxn];
int n,m,X;
inline void add(const int&fr,const int&to,const int&w){
e[fr].push_back({to,w});
}
inline bool dij(){
Qp().swap(q);
for(int t=1;t<=n;++t) d[t]=inf,Height[t]=0;
d[1]=0; Height[1]=X; q.push({0,1});
while(q.size()){
auto now=q.top();
int Cur=now.second,H=Height[Cur];
q.pop();
if(now.first>d[Cur]) continue;
for(auto t:e[Cur]){
int to=t.first;
ll len=t.second;
if(H-len>h[to]){
ll g=H-h[to]+d[Cur];
if(d[to]>g){
d[to]=g;
Height[to]=h[to];
q.push({d[to],to});
}
continue;
}
if(H-len<0){
ll g=d[Cur]+len-H+len;
if(d[to]>g){
d[to]=g;
Height[to]=0;
q.push({d[to],to});
}
continue;
}
if(d[to]>d[Cur]+len){
d[to]=d[Cur]+len;
Height[to]=H-len;
q.push({d[to],to});
continue;
}
}
}
if(d[n]==inf) return 0;
return 1;
}
int main(){
n=qr(); m=qr(); X=qr();
for(int t=1;t<=n;++t) h[t]=qr();
for(int t=1;t<=m;++t){
int t1=qr(),t2=qr(),t3=qr();
if(t3<=h[t1]) add(t1,t2,t3);
if(t3<=h[t2]) add(t2,t1,t3);
}
if(!dij()) return puts("-1"),0;
ll ans=d[n]+h[n]-Height[n];
printf("%lld\n",ans);
return 0;
}
【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)的更多相关文章
- 「JOI 2014 Final」飞天鼠
「JOI 2014 Final」飞天鼠 显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0. 到达一个点有两种情况:到达高度为0和不为0. 对于高度不为0的情况,显然花费的时间越少高度越高 ...
- loj 2759「JOI 2014 Final」飞天鼠
loj 这题有在一棵树上上升或者下降的操作,稍加分析后可以发现上升操作如果不是一定要做(指高度不足以到下一棵树或者是最后到达\(n\))就不做,下降操作也是如果不是一定要做(指到达下一棵树时高度过高) ...
- 【2018.10.1】「JOI 2014 Final」年轮蛋糕
题面 一看到求“最小值的最大值”这种问题,就能想到二分了. 二分答案,然后我们要把一圈分成三块,使这三块的大小都$\geq mid$.做法是把环展开成2倍长度的链,先钦定一个起点,然后根据前缀和再二分 ...
- 「JOI 2014 Final」裁剪线
做法一 首先将边界也视作四条裁剪线,整个平面作为一张纸,视存在 \(y = -\infty, y = +\infty, x = -\infty, x = +\infty\) 四条直线. 按照纵坐标依次 ...
- 「JOI 2017 Final」JOIOI 王国
「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...
- 「JOI 2015 Final」分蛋糕 2
「JOI 2015 Final」分蛋糕 2 题解 这道题让我想起了新年趣事之红包这道DP题,这道题和那道题推出来之后的做法是一样的. 我们可以定义dp[i][len][1] 表示从第i块逆时针数len ...
- LOJ#2351. 「JOI 2018 Final」毒蛇越狱
LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...
- 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)
LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...
- 「JOI 2015 Final」城墙
「JOI 2015 Final」城墙 复杂度默认\(m=n\) 暴力 对于点\((i,j)\),记录\(ld[i][j]=min(向下延伸的长度,向右延伸的长度)\),\(rd[i][j]=min(向 ...
随机推荐
- Android Http实现文件的上传和下载
最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂.直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就是有问题,于是自己重新整理了 ...
- 是时候了解React Native了
文章首发于简书,欢迎关注 随着科技的发展,手机开发也在向好的方向不停的转变.IOS和Android两大手机操作横空出世,称霸江湖.我们每开发一个手机软件最少都需要开发这两个终端. 两大操作系统都在不断 ...
- 从开源小白到 Apache Member,我的成长之路
我们走过的每一步路,都会留下印记,越坚实,越清晰. 近日,Apache 软件基金会(ASF)官方 Blog 宣布全球新增 40 位 Apache Member,张乎兴有幸成为其中一位. 目前,全球共有 ...
- H3C IP 地址格式和表示方法
- C# 比较两张图片是否完全相同
本文演示如何比较两张图片是否完全相同. (注意:如果是比较两张图片是否相似,则比较复杂,涉及到机器学习) 方法一:把图片保存到内存流中,然后转化成 Base64 字符串进行比较 using Syste ...
- Character.digit()的意义
最近在阅读Integet.parseInt()源码时,遇到了Character.digit()这个方法,以前没有遇到过,更没使用过,这里查了资料就记录一下. 官方说法是: java.lang.Char ...
- CF1063D Candies for Children
CF1063D Candies for Children 分类讨论题 n<=1e11, 整体上先分n<=2e6与否讨论 len长度,ans贪心的人,p就是len这一段贪心的人 n<= ...
- Fast Stone截图工具使用教程
下面是Fast Stone的显示面板,很小巧,但功能强大 一.特殊功能 1.1 添加水印 (1)选择功能栏的"Edge" (2)将要水印的图片选中,选择水印图片的放置位置,应用即可 ...
- Numpy 返回数组大小
import numpy as np a = [[1, 2], [3, 4], [5, 6]] b = np.array(a) len(a) # 3 len(b) # 3 np.size(a) # 3 ...
- 2018-10-17-Sublime-Text-好用的插件
title author date CreateTime categories Sublime Text 好用的插件 lindexi 2018-10-17 10:14:40 +0800 2018-2- ...