图的最短路径问题主要包括三种算法:
(3)Bellman (含有负权边的单源最短路径)
本文主要讲使用C++实现简单的Floyd算法,Floyd算法原理参见 Floyd–Warshall algorithm
Floyd算法简单实现(C++)
1 #include<iostream> 2 using namespace std; 3 4 #define MAXVEX 10 5 #define INFINITY 65535 6 7 typedef int Patharc[MAXVEX][MAXVEX]; 8 typedef int ShortPathTable[MAXVEX][MAXVEX]; 9 10 typedef struct { 11 int vex[MAXVEX]; 12 int arc[MAXVEX][MAXVEX]; 13 int numVertexes; 14 } MGraph; 15 16 // 构建图 17 void CreateMGraph(MGraph *G){ 18 int i, j, k; 19 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 // Floyd algorithm 67 void ShortPath_Floyd(MGraph G, Patharc P, ShortPathTable D){ 68 int i, j, k; 69 // 二重循环,初始化P, D 70 for(i = 0; i < G.numVertexes; ++i){ 71 for(j = 0; j < G.numVertexes; ++j){ 72 D[i][j] = G.arc[i][j]; 73 P[i][j] = j; 74 } 75 } 76 // 三重循环, Floyd algorithm 77 for(k = 0; k < G.numVertexes; ++k){ 78 for(i = 0; i < G.numVertexes; ++i){ 79 for(j = 0; j < G.numVertexes; ++j){ 80 if(D[i][j] > D[i][k]+D[k][j]){ 81 D[i][j] = D[i][k]+D[k][j]; 82 P[i][j] = P[i][k]; 83 } 84 } 85 } 86 } 87 } 88 89 // 打印最短路径 90 void PrintShortPath(MGraph G, Patharc P, ShortPathTable D){ 91 int i, j, k; 92 cout<<"各顶点之间的最短路径如下: "<<endl; 93 for(i = 0; i < G.numVertexes; ++i){ 94 for(j = i+1; j < G.numVertexes; ++j){ 95 cout<<"v"<<i<<"--"<<"v"<<j<<" "<<"weight: "<<D[i][j]<<" Path: "<<i<<" -> "; 96 k = P[i][j]; 97 while(k != j){ 98 cout<<k<<" -> "; 99 k = P[k][j]; 100 } 101 cout<<j<<endl; 102 } 103 cout<<endl; 104 } 105 } 106 107 int main(int argc, char const *argv[]) { 108 MGraph G; 109 Patharc P; 110 ShortPathTable D; 111 CreateMGraph(&G); 112 ShortPath_Floyd(G, P, D); 113 PrintShortPath(G, P, D); 114 return 0; 115 }
运行结果:
各顶点之间的最短路径如下: v0--v1 weight: 1 Path: 0 -> 1 v0--v2 weight: 4 Path: 0 -> 1 -> 2 v0--v3 weight: 7 Path: 0 -> 1 -> 2 -> 4 -> 3 v0--v4 weight: 5 Path: 0 -> 1 -> 2 -> 4 v0--v5 weight: 8 Path: 0 -> 1 -> 2 -> 4 -> 5 v0--v6 weight: 10 Path: 0 -> 1 -> 2 -> 4 -> 3 -> 6 v0--v7 weight: 12 Path: 0 -> 1 -> 2 -> 4 -> 3 -> 6 -> 7 v0--v8 weight: 16 Path: 0 -> 1 -> 2 -> 4 -> 3 -> 6 -> 7 -> 8 v1--v2 weight: 3 Path: 1 -> 2 v1--v3 weight: 6 Path: 1 -> 2 -> 4 -> 3 v1--v4 weight: 4 Path: 1 -> 2 -> 4 v1--v5 weight: 7 Path: 1 -> 2 -> 4 -> 5 v1--v6 weight: 9 Path: 1 -> 2 -> 4 -> 3 -> 6 v1--v7 weight: 11 Path: 1 -> 2 -> 4 -> 3 -> 6 -> 7 v1--v8 weight: 15 Path: 1 -> 2 -> 4 -> 3 -> 6 -> 7 -> 8 v2--v3 weight: 3 Path: 2 -> 4 -> 3 v2--v4 weight: 1 Path: 2 -> 4 v2--v5 weight: 4 Path: 2 -> 4 -> 5 v2--v6 weight: 6 Path: 2 -> 4 -> 3 -> 6 v2--v7 weight: 8 Path: 2 -> 4 -> 3 -> 6 -> 7 v2--v8 weight: 12 Path: 2 -> 4 -> 3 -> 6 -> 7 -> 8 v3--v4 weight: 2 Path: 3 -> 4 v3--v5 weight: 5 Path: 3 -> 4 -> 5 v3--v6 weight: 3 Path: 3 -> 6 v3--v7 weight: 5 Path: 3 -> 6 -> 7 v3--v8 weight: 9 Path: 3 -> 6 -> 7 -> 8 v4--v5 weight: 3 Path: 4 -> 5 v4--v6 weight: 5 Path: 4 -> 3 -> 6 v4--v7 weight: 7 Path: 4 -> 3 -> 6 -> 7 v4--v8 weight: 11 Path: 4 -> 3 -> 6 -> 7 -> 8 v5--v6 weight: 7 Path: 5 -> 7 -> 6 v5--v7 weight: 5 Path: 5 -> 7 v5--v8 weight: 9 Path: 5 -> 7 -> 8 v6--v7 weight: 2 Path: 6 -> 7 v6--v8 weight: 6 Path: 6 -> 7 -> 8 v7--v8 weight: 4 Path: 7 -> 8 [Finished in 1.2s]