1、
》》 广度优先搜索查找最短路径只是对无权图而言的,若图是带权图,则把从一个顶点 V0 到图中
其余任一个顶点 Vi 的一条路径(可能不止一条)上所经过边上的权值之和定义为该路径的带权
路径长度,把带权路径长度最短的那条路径称作最短路径。
》》 求解最短路径的算法通常都依赖于一种性质:两点之间的最短路径也包含了路径上其他顶点间
的最短路径。
》》 带权有向图的最短路径问题,一般情况下分为两类:
一类:单源最短路径,即求图中的某一顶点到其他各顶点的最短路径。经典的算法:Dijkstra 算法
【迪杰斯特拉算法】。
二类:每一对顶点间的最短路径 。算法实现: Floyd-Warshall 算法【弗洛伊德算法】
2、Dijkstra 算法求单源最短路径【Dijkstra 算法也是基于“ 贪心策略”的】
》》 案例:
***上图的邻接矩阵表示法:【横坐标是1~5;纵坐标是 1~5】
下面的矩阵用 arcs 表示
补充:如果两个点之间存在有向边,则用权值表示
如果两点之间不存在有向边,则用 ∞ 表示
**** 以数字 1 为源头,分别求出 1 到 2、3、4、5 的最短路径
### 借助数组 S[ ] 、数组 dist[ ]
数组 S[ ] : 表示的是最短路径的顶点
数组 dist[ ] : 表示的是从源点 1 到其他各顶点当前的最短路径
### 以 1 到 2 求最短路径为例:
1)、初始化。 数组 S[ ] 中的值为 { 1 , 2 }
dist = arcs[1] [2] = 10 【初始化设置最短路径为 10 】
2)、寻找从 1 出发最短路径的终点。从上面的矩阵中得知,此终点是 5
3)、从 5 出发 , 发现从 5 可以到达 2 。此时计算一次【1-->5 --> 2】
arcs[1][5] + arcs[5][2] = 8
发现 arcs[1][5] + arcs[5][2] < dist ,那么会将 dist 的值设置为 8 。
4)、由上的推导可知,从源头 1 到 2 的最短路径为 8 。
【1 到其他点的最短路径计算思路与此类似】
》》注意:如果边上带有负权值, Dijkstra 算法并不适用。
3、Floyd 算法求各顶点之间最短路径
》》 Floyd 算法的基本思想:初始时,对于任意两个顶点 Vi 和 Vj ,若它们之间存在边,则以此
边上的权值作为它们之间的最短路径长度;若它们之间不存在有向边,则以 ∞ 作为它们之间
的最短路径长度。以后逐步尝试在原路径中加入顶点 k (k= 0 ,1 , 2 ,,,)作为中间顶点。如果
增加中间顶点后,得到的路径比原来的路径长度减少了,则以此新路径代替原来的路径。
》》 注意:Floyd 算法允许图中有带负权值的边,但不允许有包含带负权值的边组成的回路。
Floyd 算法同样也适用于带权无向图,因为带权无向图可以看做是有往返二重边的有向图,
只要在顶点 Vi 和 Vj 之间存在无向边,就可以看成是在这两个顶点之间存在值相同的两条
有向边<Vi , Vj> 和 <Vj , Vi> 。