森森从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