对于无权图来说,可以使用广度优先遍历算法BFS,实现求单源路径最短。但是,如果图带了权值,求这种最短路径可以通过经典的Dijkstra(迪杰斯特拉)算法或者是Floyd(弗洛伊德)算法来求解。当然,这两种算法也是不容易理解的。这里以简单直白的描述方式来介绍以上两种经典算法。
一、Dijkstra算法求单源最短路径问题
算法的核心是:循环遍历所有结点,找到还没有确定的最短路径,且dist最小的顶点Vi,令Final[i] = true,以此来判断是否已找到最短路径。
dist[]:记录从源点V0到其他各顶点 当前的最短路径长度,其初值取自弧上的值
path[]:表示从源点到顶点i之间的最短路径的直接前驱结点
图表阐释:
第一轮:首先易得V1->V3和V1->V4没有直接路径,标记为无穷,第一轮分别统计V1能到的V2和V5距离分别是10、5,选最短的V1->V5(dist = 5)
第二轮:统计V1->V5->Vx的路径长度,对比V1->V2(dist=10),选最小值V1->V5->V4(dist=7)
第三轮:统计V1->V5->V4->Vx、V1->V2、V1->V5->Vx的长度,选最小值
以此类推,直到所有结点都被遍历完成
需要注意的是,Dijktra不适用于边上带负权值的情况,因为不一定会得到正确的结果,可能正负相加后会小于最短路径的路径长度了。
二、Floyd算法求各顶点之间最短路径问题
算法阐释:
第一轮:先根据领接矩阵,得到一个Vi->Vj直接路径权值,如果不存在就标无穷
第二轮:找矩阵中最大的值,例如V0->V2(dist=13),逐个扫描看看有没有其他捷径(比如V0->V1->V2),发现更短的路径10
以此类推
需要注意的是,Floyd算法虽然支持边是负值的图,但是不允许带有负权值的边组成回路,Floyd算法同样支持带权无向图,因为带权无向图可以视为权值相同往返二重边的有向图
以上两种算法都是基于贪心策略的,Dijkstra算法时间复杂度为O(V²),Floyd算法时间复杂度为O(V³)