一、问题描述
1用Floyd算法求解下图各个顶点的最短距离。写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵)。
2. 对于下图使用Dijkstra算法求由顶点a到顶点h的最短路径。
二、Floyd、Dijkstra算法原理和分析
(1)Floyd
若则dist[i][k] + dist[k][j] < dist[i][j]更新dist[i][j] 。
当三层遍历完毕之后,所有点对之间的最短路径长度就能求出来了。当然,如果只需要求某个点到其他所有点的最短距离,那么固定u,也就是说只用两层遍历就可以做到了。
最后的矩阵为
(2) Dijkstra
①在开始时,将所有节点的(到起点)距离设为无穷大;全部(包括起点)纳入不确定集合中。
②选择起点,将其(到起点)距离设为0。因为自己到自己的距离肯定为0。
③循环地从不确定集合中选择一个节点,加入确定集合。
当不确定集合为空时,此循环结束。
三、代码设计
void Floyd()
{
int dist[maxn][maxn]; // dist存储i到j的最短距离
for(int k = 1; k <= n; k++)
for(int i = 1;i <= n; i++)
for(int j = 1; j <= n; j++)
if(dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j]; // 不断更新最短距离
}
void dijkstra(Vertex s){ /*初始化所有节点*/
for each Vertex v
{
v.dist = INFINITY;//将所有节点到起点 s 的距离设为无穷大
v.known = false;//将所有节点标为未确定,即还未加入路径
}
s.dist = 0; //将起点自己的dist设为0
for( ; ; ){ //一直循环,直到触发break
Vertex v = smallest distance and unknown vertex; //从未确定的点集中取出距离起点最近的点
if(v==null) break; //若取到的点是空,即已无点可取
v.known = true; //将该点加入确定点
for each Vertex w adjacent to v //只遍历、选出与新加入节点v相连的节点w
if( !w.known ) //如果w还是未确定的点
//因为距离还未确定,所以比较,若是更近则更新
if(v.dist + cvw < w.dist){ //自认,cvw是指当前所选节点w与新加入节点v的距离//
w.dist = v.dist + cvw;
w.path = v;
}
}
}
四、算法复杂程度
Floyd:O(n^3)
Dijkstra:O(n^2)
五、源代码
https://github.com/yttb/hello-world