开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情
7.1 最短路径问题
7.1.1 概述
a点到b点之间路径可达最短的一条线路就是最短路径
或者说是从a点到b点最省钱的路线,这也是一种最短路的问题 ->这种情况下什么是长什么是短?
//区别就在边上的权重(我们赋予了他们什么意义),比如我们要找最便宜的路径,那么两点之间的那个边的权重就应该定义成票的价格
//我们要找的就是票的价格的和是最小的那条路
假如我们要找的是a站点到b站点最快的那个路径,这时候什么叫快?
//是 经停的站最少的快 还是说 途经时间最短的快。在这里我们选择前者
//这时候边的权重就定义为1,经停站的个数就是每条边加起来的了
最短路径问题的抽象
在网络中,求两个不同顶点之间的所有路径中,边的权值之和最小的那一条路径
- 这条路径就是两点之间的最短路径(ShortestPath)
- 第一个顶点为源点(Source)
- 最后一个顶点为终点(Destination)
问题分类
-
单源最短路问题:
- 从某固定源点出发,求其到所有其他顶点的最短路径
- (有向)无权图
- (无向)有权图
-
多源最短路径问题:
- 求任意两顶点间的最短路径
7.1.2 无权图的单源最短路
- 按照递增(非递减)的顺序找出到各个顶点的最短路
- 这是一圈一圈向外扫描的(BFS广度优先搜索),同时也就解决了James Bond从孤岛跳上岸,最少需要多少步
上图中if中判断的条件里的是BFS的,在这里是不需要的,这里需要的是:
dist[W] = S到W的最短距离//无穷大、无穷小、-1都可以。因为这些数可以一看到就知道还未被访问过,下面采用-1的方式
dist[S] = 0//初始值是0,表示他到他自己的距离
path[W] = S到W的路上经过的某顶点//记录路径,对每一个顶点W,把源点到w的路上一定要经过的某一个顶点存在这个path里面
单源最短函数算法
void Unweighted ( Vertex S )//unweighted是无权的意思
{
Enqueue(S,Q);
while(!IsEmpty(Q)){
V = Dequeue(Q);//每次弹出来一个顶点,就意味着这个顶点到s的最短路径已经被找到了
for ( V 的每一个邻接点 W )
if( dist[W] == -1 ){//正常的数都是正数,-1是属于不会被访问过的
dist[W] == dist[V]+1;//这个时候W的最短距离就找到了
path[W] = V//谁是S到W路上必经的顶点呢?那就是他的前一个顶点(V是顶点的编号)。记录下来这个的作用是:顺着path这个数组一个一个往前推,直到推到源点得到一个反向的路径(然后将其压到堆栈里面(堆栈起反序作用,后序先出),从而得到正确的路径)
Enqueue(W,Q);
}
}
}
如果有|V|个顶点和|E|条边的图用邻接表存储,则算法的时间复杂度是多少?
是 T = O(|V|+|E|)
7.2.2-s 无权图的单源最短路示例
void Unweighted ( Vertex S )//unweighted是无权的意思
{
Enqueue(S,Q);
while(!IsEmpty(Q)){//这是判断他是不是为空再决定要不要进行下去
V = Dequeue(Q);
for ( V 的每一个邻接点 W )
if( dist[W] == -1 ){//正常的数都是正数,-1是属于不会被访问过的
dist[W] == dist[V]+1;
path[W] = V
Enqueue(W,Q);
}
}
}
//dist是点到源点的最短距离
//path是指当前点在那条路径上
//所以所有的信息就都可以从表格中得到