虽然笔试已经过去,还是决定把这个求有向图中某源点到图中任意一点的最短路径的经典算法温习一遍。
Dijkstra算法原理:
Dijkstra算法牵涉到几个非常重要的状态变量
1)长度为N的一维数组Dist[N],用来存放从源点到图中其它节点的最短路径长度;
2)Dijkstra算法需要维护两个非常重要的集合,假设这两个集合分别为V和S,V集合用来存放目前还没有计算节点,S集合用来存放已经得到最短路径的节点集合。刚开始时,集合V包含图中所有节点,集合S为空。
3)辅助二维数组path_matrix,用来记录源点到图中其它每个节点的最短路径所经过的顶点结合。
Dijkstra算法执行流程;
1 初始化集合V和S;
2 利用图的邻接矩阵来初始化Dist[N]数组;
3 从Dist[N]数组中选择最小的元素,假设此最小元素对应的节点编号为i,即节点i;
4 将节点i加入集合S中,同时从集合V中删除节点i;
5 根据节点i来更新距离数组Dist[N],只更新源点到那些处于集合V-S中的节点之间的距离;
if (Dist[j] > Dist[i]+matrix[i][j] )
Dist[j]=Dist[i]+matrix[i][j];
6 回到3执行,直至集合V为空。
01 #include <iostream>
02 using namespace std;
03
04 #define N 6
05 #define INFINITY 65535
06
07 int matrix[N][N] = {
08 {-1, -1, 10, -1, 30, 100},
09 {-1, -1, 5, -1, -1, -1},
10 {-1, -1, -1, 50, -1, -1},
11 {-1, -1, -1, -1, -1, 10},
12 {-1, -1, -1, 20, -1, 60},
13 {-1, -1, -1, -1, -1, -1}
14 };
15
16 void
17 shortest_path_dijkstra (int v0, bool path_matrix[][N], int *Dist)
18 {
19 bool final[N];
20 int i = 0, j = 0;
21
22 /* initialize shortest path table */
23 for ( i = 0; i < N ; ++i ) {
24 final[i] = false;
25 Dist[i] = (matrix[v0][i] != -1) ? matrix[v0][i] : INFINITY;
26
27 for ( j = 0; j < N; ++j ) {
28 path_matrix[i][j] = false;
29 }
30
31 if ( Dist[i] != -1 ) {
32 path_matrix[i][v0] = true;
33 path_matrix[i][i] = true;
34 }
35 }
36
37 Dist[v0] = 0;
38 final[v0] = true;
39
40 int n = 0;
41 int min = 0;
42 int index_of_minimum = 0;
43 for ( i = 1; i < N; ++i ) {
44 /* search minimum element in Dist array */
45 min = INFINITY;
46 for ( j = 0; j < N; ++j ) {
47 if ( !final[j] && Dist[j] < min ) {
48 min = Dist[j];
49 index_of_minimum = j;
50 }
51 }
52
53 final[index_of_minimum] = true;
54
55 /* update Dist array and path matrix */
56 for ( int k = 0; k < N; ++k ) {
57 if ( !final[k] &&
58 matrix[index_of_minimum][k] != -1 &&
59 min + matrix[index_of_minimum][k] < Dist[k] ) {
60 Dist[k] = min + matrix[index_of_minimum][k];
61
62 /* update path matrix */
63 for ( n = 0; n < N; ++n ) {
64 path_matrix[k][n] = path_matrix[index_of_minimum][n];
65 }
66
67 path_matrix[k][k] = true;
68 }
69 }
70 }
71 }
72
73 int main (void)
74 {
75 bool path_matrix[N][N];
76 int Dist[N];
77 shortest_path_dijkstra (0, path_matrix, Dist);
78
79 /* output shortest path */
80 for ( int i = 0; i < N; ++i ) {
81 cout << "v0-->>v" << i << ": ";
82 for ( int j = 0; j < N; ++j ) {
83 if ( path_matrix[i][j] ) {
84 cout << "v" << j << " ";
85 }
86 }
87 cout << endl;
88 }
89
90 return 0;
91 }
92
输出结果
93 [doyle@phuang algorithm]$ ./a.out
94 v0-->>v0: v0
95 v0-->>v1: v0 v1
96 v0-->>v2: v0 v2
97 v0-->>v3: v0 v3 v4
98 v0-->>v4: v0 v4
99 v0-->>v5: v0 v3 v4 v5
from http://hi.baidu.com/lxsbupt/blog/item/03f3d5d73a131dd7a044df63.html