【团体程序设计天梯赛】L3-028 森森旅游

文章描述了一个旅行者在多个城市间使用现金和旅游金支付路费的问题,通过构建现金正向图和旅游金反向图,利用Dijkstra算法和小根堆优化求解从1号城市到n号城市的最小费用路径,同时考虑汇率更新的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

森森从1号城市出发,先用现金支付路费,到某个城市后将所剩全部现金换成旅游金,用旅游金支付剩下的路费,直至到达n号城市。也就是说,我们要判断每一个转折城市k,求【1号城市到k号城市所需现金】+【k号城市到n号城市所需旅游金/k号城市的汇率】,值最小的那个,就是我们所求答案。

其实也是求两个单源最短路问题,一个是点1到各点所需的最少现金,另一个则是点n到各点所需的最少旅游金(前面分析的是说各点到点n的最少旅游金,但用n次dijkstra时间复杂度太高,而且我们只需要各点到点n的距离,各点到其他点的距离是没有用的)。第一个最短路我们以现金为距离建立正向图即可,第二个最短路我们以旅游金为距离建立反向图,注意需要两个head数组。由于点较多,我们可以用小根堆优化的dijkstra算法。

处理完两个距离数组后,我们就可以求解了。由于每次查询我们只需输出最少的现金数(最优解),因此我们仍可以用小根堆优化,先求出更新汇率前的所有解,加入堆。每次更新的时候,求出新解,入堆,小根堆的堆顶就是我们要的答案(但要及时弹出过时的答案,因为每次汇率更新都是建立在之前汇率调整的基础上的)。

#include <iostream>
#include <cstring>
#include <queue>
#define N 100010
#define M 400010
#d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值