loj

这题有在一棵树上上升或者下降的操作,稍加分析后可以发现上升操作如果不是一定要做(指高度不足以到下一棵树或者是最后到达\(n\))就不做,下降操作也是如果不是一定要做(指到达下一棵树时高度过高)就不做,因为如果提前做了,可能会导致后面要浪费一些步数使得移动合法.然后这个移动过程就会分成两段,先是一直移动或者下降,不用上升,然后会每次上升再移动,一直到终点

先看前一段的移动,如果移动的时候正好能移到下一棵树就直接移,如果移的时候高度过高就往下移一点直到能正好移动到下一棵树上.这里对每个点记\(di_x\)表示从起点到这里用了多久.注意我们还需要知道在某个树上所在的高度,由于这一部分没有上升操作,并且每过一个单位时间会下降1,所以在某点高度为\(X-di_x\).然后这个\(di_x\)应当记的是最短用时,因为用时越短,在的位置也越高,然后对后续转移也越有利,至于有可能要强制往下移,那只要在该移的时候向下移动就行,用时短一定不必用时长劣

还有一种情况,是移到下一棵树会移到\(<0\)的高度,这时候我们就要往上移,移到能飞到下一棵树的位置,然后往下一棵树移.移到下一棵树后高度会变为0,这时候对于任何移动,我们都是先往上移\(t_i(t_i\le H_x)\),然后飞到下一棵树,所以用时都是\(2t_i\).那么上面两种情况就可以分别用\(dij\)来转移了.注意如果在第一种移动过程中移到了\(n\),那么就可以更新答案了,所以最终答案为\(min(\)这种情况的贡献\(,dis_n+H_n)\)

#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db long double using namespace std;
const int N=1e5+10;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
};
int n,m,X,h[N],e[N*3][3];
struct node
{
LL x,d;
bool operator < (const node &bb) const {return d>bb.d;}
};
priority_queue<node> q,qq;
int to[N<<4],nt[N<<4],w[N<<4],hd[N],tot=1;
void add(int x,int y,int z)
{
++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;
}
LL di[N],ans=1ll<<50; int main()
{
n=rd(),m=rd(),X=rd();
for(int i=1;i<=n;++i) h[i]=rd();
for(int i=1;i<=m;++i)
for(int j=0;j<=2;++j)
e[i][j]=rd();
for(int i=1;i<=m;++i)
{
int x=e[i][0],y=e[i][1],z=e[i][2];
add(x,y,z),add(y,x,z);
}
memset(di,0x3f3f3f,sizeof(LL)*(n+1));
qq.push((node){1,di[1]=0});
LL he=X;
while(!qq.empty())
{
int x=qq.top().x;
LL d=qq.top().d;
qq.pop();
if(d>di[x]) continue;
if(x==n) ans=min(ans,di[x]+h[n]-(he-di[x]));
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(he-di[x]-w[i]<=0&&w[i]<=h[x]) q.push((node){y,di[x]+w[i]-(he-di[x]-w[i])});
else
{
LL dt=max(0ll,he-di[x]-w[i]-h[y]);
if(di[y]>di[x]+w[i]+dt&&di[x]+w[i]+dt<=he) qq.push((node){y,di[y]=di[x]+w[i]+dt});
}
}
}
memset(hd,0,sizeof(int)*(n+1)),tot=1;
for(int i=1;i<=m;++i)
{
int x=e[i][0],y=e[i][1],z=e[i][2];
if(h[x]>=z) add(x,y,z<<1);
if(h[y]>=z) add(y,x,z<<1);
}
memset(di,0x3f3f3f,sizeof(LL)*(n+1));
while(!q.empty())
{
int x=q.top().x;
LL d=q.top().d;
q.pop();
if(d>di[x]) continue;
if(d<di[x]) di[x]=d;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(di[y]>di[x]+w[i])
q.push((node){y,di[y]=di[x]+w[i]});
}
}
ans=min(ans,di[n]+h[n]);
printf("%lld\n",ans<(1ll<<50)?ans:-1);
return 0;
}

loj 2759「JOI 2014 Final」飞天鼠的更多相关文章

  1. 【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)

    [题解]LOJ2759. 「JOI 2014 Final」飞天鼠(最短路) 考虑最终答案的构成,一定是由很多飞行+一些上升+一些下降构成. 由于在任何一个点上升或者下降代价是一样的,所以: 对于上升操 ...

  2. 「JOI 2014 Final」飞天鼠

    「JOI 2014 Final」飞天鼠 显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0. 到达一个点有两种情况:到达高度为0和不为0. 对于高度不为0的情况,显然花费的时间越少高度越高 ...

  3. LOJ#2351. 「JOI 2018 Final」毒蛇越狱

    LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...

  4. LOJ#2764. 「JOI 2013 Final」JOIOI 塔

    题目地址 https://loj.ac/problem/2764 题解 真的想不到二分...不看tag的话... 考虑二分答案转化为判定问题,那么问题就变成了能不能组合出x个JOI/IOI,考虑贪心判 ...

  5. LOJ#2343. 「JOI 2016 Final」集邮比赛 2

    题目地址 https://loj.ac/problem/2343 题解 首先处理出\(f[i]\)表示以当前位置开头(J,O,I)的合法方案数.这个显然可以\(O(n)\)处理出来.然后考虑在每个位置 ...

  6. loj 3014「JOI 2019 Final」独特的城市

    loj 我本来是直接口胡了一个意思一样的做法的,但是因为觉得有点假+实现要用并查集(?)就卡了好一会儿... 对于一个点\(x\)来说,独特的点一定在它的最长链上,如果有独特的点不在最长链上,那么最长 ...

  7. loj 2336「JOI 2017 Final」绳

    loj 首先,所有位置最多被染色一次,因为要染多次的话,还不如一开始就染成最终的颜色.并且你可以一开始就染好色 因为最终长度为2,那么如果染完后这个序列可以被折完,那么首先最多只有两种颜色,还有就是要 ...

  8. 【2018.10.1】「JOI 2014 Final」年轮蛋糕

    题面 一看到求“最小值的最大值”这种问题,就能想到二分了. 二分答案,然后我们要把一圈分成三块,使这三块的大小都$\geq mid$.做法是把环展开成2倍长度的链,先钦定一个起点,然后根据前缀和再二分 ...

  9. loj#2334 「JOI 2017 Final」JOIOI 王国

    分析 二分答案 判断左上角是否满足 为了覆盖所有范围 我们依次把右下角,左上角,右上角移动到左上角 代码 #include<bits/stdc++.h> using namespace s ...

随机推荐

  1. 使用 PM2 将 Node.js 的集群变得更加容易

    介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...

  2. iommu是干什么的呢?

    答: 如普通的mmu,将虚拟内存地址转换为物理地址,不同的是,iommu是将设备访问的虚拟地址转换为物理地址

  3. Permission权限大全

    访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...

  4. 利用phpStudy 探针 提权网站服务器

    声明: 本教程仅仅是演示管理员安全意识不强,存在弱口令情况.网站被非法入侵的演示,请勿用于恶意用途! 今天看到论坛有人发布了一个通过这phpStudy 探针 关键字搜索检索提权网址服务器,这个挺简单的 ...

  5. 纯CSS实现加载转圈样式

    不同的项目中对于等待加载时转圈圈的样式是不同的,有的是传统的转圈的gif图片,见得比较多的是将转圈圈的换成了可爱的图标.有时候项目中加入等待加载的图片会很违和,不符合美观,所以需要用CSS做一个.下面 ...

  6. Mysql执行查询语句慢的解决方式

    MySQL使用的是InnoDB引擎.不同于MyISAM引擎只提供表锁,InnoDB提供不同级别的锁.但是在我们日常的操作过程中经常由于对数据库不当的SQL操作导致出现长时间的锁,造成其他的SQL语句长 ...

  7. Linux下通过crontab命令来实现定时任务

    一.crond的介绍 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cr ...

  8. C2B电商三种主要模式的分析_数据分析师

    C2B电商三种主要模式的分析_数据分析师 在过去的一年中电商领域血雨腥风,尤其是天猫.京东.苏宁.当当.易讯等B2C电商打得不亦乐乎.而随着B2C领域竞争进入白热化阶段,C2B模式也在天猫" ...

  9. LOGIT REGRESSION

    Version info: Code for this page was tested in SPSS 20. Logistic regression, also called a logit mod ...

  10. LeetCode.1200-最小绝对值差(Minimum Absolute Difference)

    这是小川的第次更新,第篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第268题(顺位题号是1200).给定一个由不同的整数组成的数组arr,找到所有对元素,其中任意两个元素的绝 ...