前言 \color{green}{\texttt{前言}} 前言
在之前的博客中,我们不止一次地用到了最短路算法(如 spfa
和 dijkstra
),然而,即便它们可以被用来求解各种各样、形形色色的问题,但是我们只能求出起点到一个点或一个点到终点的距离。
在现实生活中,我们常常不仅需要这个距离,还需要这个路径(即我怎么走),可不可以在求解最短路的同时求解其最短路径呢?答案是肯定的。
路径的记录 \color{green}{\texttt{路径的记录}} 路径的记录
在这里,我们以 dijkstra
算法为例,讲如何记录路径。由于各种最短路算法都有惊人的相似性,大家可以类推(记 n n n 为节点总数)。
回忆一下 dijkstra
算法的过程,最重要的一个操作就是松弛操作,它长这样:
//(u,v)是图上一条边,dist表示距离
//而d[i]表示起点到i的最短路长度
if (d[v]>d[u]+dist[u][v]){
d[v]=d[u]+dist[u][v];//松弛
//因算法而异,把v加入不同的队列
}
可不可以在这里下下功夫,随便把路径给记录下来呢?答案是肯定的。
直接把完整的路径记录下来不太可行,所以我们只针对每个节点 u u u,记录一个 t u t_{u} tu,表示在最短路径中,我们从点 t u t_u tu 走到点 u u u。
如何求出所有的 t i ( 1 ≤ i ≤ n ) t_i(1 \leq i \leq n) ti(1≤i≤n)?简单,我们在松弛操作的时候,随便把 t v t_v tv 改为 u u u 即可。最短路结束后,所有的 t i ( 1 ≤ i ≤ n ) t_i(1 \leq i\leq n) ti(1≤i≤n) 就被求出来了。
(红笔圈出来的地方就是代码唯一被改动了的地方——松弛操作)
路径的输出。如何输出完整的路径?很简单,一个递归即可。
(当然了,注意要先单独输出 s s s,即起点)
例:UVA11374 Airport Express \color{green}{\texttt{例:UVA11374 Airport Express}} 例:UVA11374 Airport Express
[Problem] \color{blue}{\texttt{[Problem]}} [Problem]
在 Iokh
市中,机场快线
是市民从市内去机场的首选交通工具。机场快线
分为 经济线
和 商业线
两种,线路、速度和价钱都不同。你有一张商业线车票,可以且只可以坐一站商业线,而其他时候只能乘坐经济线。假设换乘时间忽略不计,你的任务是找一条去机场最快的线路。
【输入格式】:
输入包含多组数据。
每组数据第一行为 3