图的最短路径问题主要包括三种算法:
(3)Bellman (含有负权边的单源最短路径)
本文主要讲使用C++实现简单的Dijkstra算法
Dijkstra算法简单实现(C++)
1 #include<iostream> 2 #include<stack> 3 using namespace std; 4 5 #define MAXVEX 9 6 #define INFINITY 65535 7 8 typedef int Patharc[MAXVEX]; 9 typedef int ShortPathTable[MAXVEX]; 10 11 typedef struct { 12 int vex[MAXVEX]; 13 int arc[MAXVEX][MAXVEX]; 14 int numVertexes; 15 } MGraph; 16 17 // 构建图 18 void CreateMGraph(MGraph *G){ 19 int i, j, k; 20 // 初始化图 21 G->numVertexes = 9; 22 for(i = 0; i < G->numVertexes; ++i){ 23 G->vex[i] = i; 24 } 25 for(i = 0; i < G->numVertexes; ++i){ 26 for(j = 0; j < G->numVertexes; ++j){ 27 if(i == j) 28 G->arc[i][j] = 0; 29 else 30 G->arc[i][j] = G->arc[j][i] = INFINITY; 31 } 32 } 33 34 G->arc[0][1] = 1; 35 G->arc[0][2] = 5; 36 37 G->arc[1][2] = 3; 38 G->arc[1][3] = 7; 39 G->arc[1][4] = 5; 40 41 G->arc[2][4] = 1; 42 G->arc[2][5] = 7; 43 44 G->arc[3][4] = 2; 45 G->arc[3][6] = 3; 46 47 G->arc[4][5] = 3; 48 G->arc[4][6] = 6; 49 G->arc[4][7] = 9; 50 51 G->arc[5][7] = 5; 52 53 G->arc[6][7] = 2; 54 G->arc[6][8] = 7; 55 56 G->arc[7][8] = 4; 57 58 // 设置对称位置元素值 59 for(i = 0; i < G->numVertexes; ++i){ 60 for(j = i; j < G->numVertexes; ++j){ 61 G->arc[j][i] = G->arc[i][j]; 62 } 63 } 64 } 65 66 void ShortPath_Dijkstra(MGraph G, int v0, Patharc P, ShortPathTable D){ 67 int final[MAXVEX]; 68 int i; 69 for(i = 0; i < G.numVertexes; ++i){ 70 final[i] = 0; 71 D[i] = G.arc[v0][i]; 72 P[i] = 0; 73 } 74 D[v0] = 0; 75 final[v0] = 1; 76 for(i = 0; i < G.numVertexes; ++i){ 77 int min = INFINITY; 78 int j, k, w; 79 80 for(j = 0; j < G.numVertexes; ++j){// 查找距离V0最近的顶点 81 if(!final[j] && D[j] < min){ 82 k = j; 83 min = D[j]; 84 } 85 } 86 final[k] = 1; 87 for(w = 0; w < G.numVertexes; ++w){// 更新各个顶点的距离 88 if(!final[w] && (min + G.arc[k][w]) < D[w]){ 89 D[w] = min + G.arc[k][w]; 90 P[w] = k; 91 } 92 } 93 } 94 } 95 96 // 打印最短路径 97 void PrintShortPath(MGraph G, int v0, Patharc P, ShortPathTable D){ 98 int i, k; 99 stack<int> path; 100 cout<<"顶点v"<<v0<<"到其他顶点之间的最短路径如下: "<<endl; 101 for(i = 0; i < G.numVertexes; ++i){ 102 if(i == v0) continue; 103 cout<<"v"<<v0<<"--"<<"v"<<i<<" weight: "<<D[i]<<" Shortest path: "; 104 path.push(i); 105 int k = P[i]; 106 while(k != 0){ 107 path.push(k); 108 k = P[k]; 109 } 110 path.push(v0); 111 while(!path.empty()){ 112 if(path.size() != 1) 113 cout<<path.top()<<"->"; 114 else 115 cout<<path.top()<<endl; 116 path.pop(); 117 } 118 } 119 } 120 121 int main(int argc, char const *argv[]) { 122 int v0 = 0; // 源点 123 MGraph G; 124 Patharc P; 125 ShortPathTable D; 126 CreateMGraph(&G); 127 ShortPath_Dijkstra(G, v0, P, D); 128 PrintShortPath(G, v0, P, D); 129 return 0; 130 }
运行结果
顶点v0到其他顶点之间的最短路径如下: v0--v1 weight: 1 Shortest path: 0->1 v0--v2 weight: 4 Shortest path: 0->1->2 v0--v3 weight: 7 Shortest path: 0->1->2->4->3 v0--v4 weight: 5 Shortest path: 0->1->2->4 v0--v5 weight: 8 Shortest path: 0->1->2->4->5 v0--v6 weight: 10 Shortest path: 0->1->2->4->3->6 v0--v7 weight: 12 Shortest path: 0->1->2->4->3->6->7 v0--v8 weight: 16 Shortest path: 0->1->2->4->3->6->7->8 [Finished in 1.8s]