一、最短路径的定义

  在网图和非网图中,最短路径的含义是不同的。由于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径;而对于网图来说,最短路径是指两顶点之间经过的边上权值之和最少的路径,并且称路径上的第一个顶点是源点,第二个顶点是终点。显然,非网图可以理解为所有的边的权值都为1的网图。

  

  二、Dijkstra算法

  1.Dijkstra算法描述

  有向网中从源点V0到其他终点的最短路径的过程是:初始情况下,若从源点到该顶点有弧,则存在一条路径,路径长度即为该弧上的权值。每求得一条到达某个终点w的最短路径,就需要检查是否存在经过这个顶点w的其他路径(即是否存在从顶点w出发到尚未求得最短路径顶点的弧),若存在,判断其长度是否比当前求得的路径长度短,若是,则修改当前路径。同时,保存当前已得到的从源点到各个终点的最短路径。

  2.Dijkstra算法的C语言代码实现

  1. /* Dijkstra算法,求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度D[v] */
  2. /* P[v]的值为前驱顶点下标,D[v]表示v0到v的最短路径长度和 */
  3. void ShortestPath_Dijkstra(MGraph G, int v0, Patharc *P, ShortPathTable *D)
  4. {
  5. int v,w,k,min;
  6. int final[MAXVEX];/* final[w]=1表示求得顶点v0至vw的最短路径 */
  7. for(v=; v<G.numVertexes; v++) /* 初始化数据 */
  8. {
  9. final[v] = ; /* 全部顶点初始化为未知最短路径状态 */
  10. (*D)[v] = G.arc[v0][v];/* 将与v0点有连线的顶点加上权值 */
  11. (*P)[v] = -; /* 初始化路径数组P为-1 */
  12. }
  13.  
  14. (*D)[v0] = ; /* v0至v0路径为0 */
  15. final[v0] = ; /* v0至v0不需要求路径 */
  16. /* 开始主循环,每次求得v0到某个v顶点的最短路径 */
  17. for(v=; v<G.numVertexes; v++)
  18. {
  19. min=INFINITY; /* 当前所知离v0顶点的最近距离 */
  20. for(w=; w<G.numVertexes; w++) /* 寻找离v0最近的顶点 */
  21. {
  22. if(!final[w] && (*D)[w]<min)
  23. {
  24. k=w;
  25. min = (*D)[w]; /* w顶点离v0顶点更近 */
  26. }
  27. }
  28. final[k] = ; /* 将目前找到的最近的顶点置为1 */
  29. for(w=; w<G.numVertexes; w++) /* 修正当前最短路径及距离 */
  30. {
  31. /* 如果经过v顶点的路径比现在这条路径的长度短的话 */
  32. if(!final[w] && (min+G.arc[k][w]<(*D)[w]))
  33. { /* 说明找到了更短的路径,修改D[w]和P[w] */
  34. (*D)[w] = min + G.arc[k][w]; /* 修改当前路径长度 */
  35. (*P)[w]=k;
  36. }
  37. }
  38. }
  39. }

Dijkstra算法

  3.Dijkstra算法算法的Java语言代码实现

  1. package bigjun.iplab.adjacencyMatrix;
  2.  
  3. public class TheShortestPath_Dijkstra {
  4.  
  5. private static int[] P; // 若P[v]=w,则表示V0到Vv的最短路径上,顶点Vv的前驱是Vw
  6. private static int[] D; // V0到其他各个顶点的最小权值
  7. public final static int INFINITY = Integer.MAX_VALUE;
  8.  
  9. public static void Dijkstra(AdjacencyMatrixGraphINF G, Object V0) throws Exception {
  10.  
  11. int v;
  12. int v0 = G.locateVex(V0);
  13. int vexNum = G.getVexNum(); // 顶点数
  14. P = new int[vexNum];
  15. D = new int[vexNum];
  16. boolean[] finish = new boolean[vexNum]; // finish[v]=true时,说明已经求得了从v0到v的最短路径
  17. for (v = 0; v < vexNum; v++) {
  18. finish[v] = false;
  19. D[v] = G.getArcs()[v0][v];
  20. P[v] = -1;
  21. }
  22. D[v0] = 0;
  23. finish[v0] = true; // 已求得v0到v0的最短路径
  24. v = -1;
  25. for (int i = 1; i < vexNum; i++) { // 求得V0到顶点Vi的最短路径
  26. int min = INFINITY;
  27. for (int w = 0; w < vexNum; w++) { // 求得当前到v0顶点的最近距离
  28. if (!finish[w]) {
  29. if (D[w] < min) {
  30. v = w;
  31. min = D[w];
  32. }
  33. }
  34. }
  35. finish[v] = true;
  36. // 在已知V0与V[v]的最短路径的基础上,对V
  37. for (int w = 0; w < vexNum; w++) { // 更新当前最短路径及距离
  38. if (!finish[w] && G.getArcs()[v][w] < INFINITY && (min + G.getArcs()[v][w] < D[w])) {
  39. D[w] = min + G.getArcs()[v][w];
  40. P[w] = v;
  41. }
  42. }
  43. }
  44. System.out.println("V0到其他各个顶点的最短路径的权值之和为: ");
  45. for (int i = 1; i < D.length; i++) {
  46. System.out.println("V0-" + G.getVex(i).toString() + ": " + D[i]);
  47. }
  48. System.out.println();
  49. System.out.println("V0到其他各个顶点的最短路径的倒序为: ");
  50. for (int i = 1; i < vexNum; i++) {
  51. System.out.print("从" + G.getVex(i) + "到V0的最短路径为: ");
  52. int j = i;
  53. while (P[j] != -1) {
  54. System.out.print(G.getVex(P[j]) + " ");
  55. j=P[j];
  56. }
  57. System.out.println();
  58. }
  59. }
  60.  
  61. }

  4.Dijkstra算法执行过程的举例说明

  以下面的图为例:

  

  测试类:

  1. // 手动创建一个用于测试最短路径算法的无向网
  2. public static AdjacencyMatrixGraphINF createUDNByYourHand_ForTheShortestPath() {
  3. Object vexs_UDN[] = {"V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8"};
  4. int arcsNum_UDN = 16;
  5. int[][] arcs_UDN = new int[vexs_UDN.length][vexs_UDN.length];
  6. for (int i = 0; i < vexs_UDN.length; i++) // 构造无向图邻接矩阵
  7. for (int j = 0; j < vexs_UDN.length; j++)
  8. if (i==j) {
  9. arcs_UDN[i][j]=0;
  10. } else {
  11. arcs_UDN[i][j] = arcs_UDN[i][j] = INFINITY;
  12. }
  13.  
  14. arcs_UDN[0][1] = 1;
  15. arcs_UDN[0][2] = 5;
  16. arcs_UDN[1][2] = 3;
  17. arcs_UDN[1][3] = 7;
  18. arcs_UDN[1][4] = 5;
  19. arcs_UDN[2][4] = 1;
  20. arcs_UDN[2][5] = 7;
  21. arcs_UDN[3][4] = 2;
  22. arcs_UDN[3][6] = 3;
  23. arcs_UDN[4][5] = 3;
  24. arcs_UDN[4][6] = 6;
  25. arcs_UDN[4][7] = 9;
  26. arcs_UDN[5][7] = 5;
  27. arcs_UDN[6][7] = 2;
  28. arcs_UDN[6][8] = 7;
  29. arcs_UDN[7][8] = 4;
  30.  
  31. for (int i = 0; i < vexs_UDN.length; i++) // 构造无向图邻接矩阵
  32. for (int j = i; j < vexs_UDN.length; j++)
  33. arcs_UDN[j][i] = arcs_UDN[i][j];
  34. return new AdjMatGraph(GraphKind.UDN, vexs_UDN.length, arcsNum_UDN, vexs_UDN, arcs_UDN);
  35. }
  36.  
  37. public static void main(String[] args) throws Exception {
  38.  
  39. AdjMatGraph UDN_Graph_TSP = (AdjMatGraph) createUDNByYourHand_ForTheShortestPath();
  40. TheShortestPath_Dijkstra.Dijkstra(UDN_Graph_TSP, "V0");
  41. }

  输出:

  1. V0到其他各个顶点的最短路径的权值之和为:
  2. V0-V1: 1
  3. V0-V2: 4
  4. V0-V3: 7
  5. V0-V4: 5
  6. V0-V5: 8
  7. V0-V6: 10
  8. V0-V7: 12
  9. V0-V8: 16
  10.  
  11. V0到其他各个顶点的最短路径的倒序为:
  12. V1V0的最短路径为:
  13. V2V0的最短路径为: V1
  14. V3V0的最短路径为: V4 V2 V1
  15. V4V0的最短路径为: V2 V1
  16. V5V0的最短路径为: V4 V2 V1
  17. V6V0的最短路径为: V3 V4 V2 V1
  18. V7V0的最短路径为: V6 V3 V4 V2 V1
  19. V8V0的最短路径为: V7 V6 V3 V4 V2 V1

  结合例子分析代码执行过程:

  

  1. 初始化:
    v0=0finish数组都为false,说明所有的点都未求得最短路径,D数组是第一行的权值,P00,10,20,11,22,33trueD[0]=0,finish[0]= true,v=-1
    i=1时,此时D={0,1,5,INF,INF,INF,INF,INF,INF},finish={TFFFFFFFF},v=1,min=D[1]=1,finish[1]=true,
        现在V0-V1-V2=D[2]=min+3=4,V0-V1-V3=D[3]=min+7=8,V0-V1-V4=D[4]=min+5=6,
        p2=1,p3=1,p4=1
    i=2时,此时D={0,1,4,8,6,INF,INF,INF,INF},finish={TTFFFFFFF},v=2,min=D[2]=4,finish[2]=true,
        现在V0-V2-V4=D[4]=4+1=5,V0-V2-V5=D[5]=4+7=11,
        p4=2,p5=2
    i=3时,此时D={0,1,4,8,5,11,INF,INF,INF},finish={TTTFFFFFF},v=4,min=D[4]=5,finish[4]=true,
        V0-V4-V3=D[3]=5+2=7,V0-V4-V5=D[5]=5+3=8,V0-V4-V6=D[6]=5+6=11V0-V4-V7=D[7]=5+9=14
        p3=4,p5=4,p6=4,p7=4
    ...
  2. i=8时,此时D={0,1,4,7,5,8,10,12,16},finish={TTTTTTTTF},v=8,min=D[8]=16,finish[8]=true,
    此时,数组p为:[0,0,1,4,2,4,3,6,7]即由于p8=7,p7=6,p6=3,p3=4,p4=2,p2=1,p1=0得到从V8V0的倒序为:V8-V7-V6-V3-V4-V2-V1-V0

  三、Floyd算法

  1.Floyd算法描述

  Floyd算法适用于要求所有顶点至所有顶点的最短路径的。其算法思路是:

  

  首先定义左边两个矩阵D和P,D矩阵表示顶点到顶点的最短路径权值之和,P矩阵表示顶点的最小路径的前驱矩阵。

  例如,从v1-v0-v2时,从D矩阵可以看出,D[1][0]+D[0][2]=2+1=3,而D[1][2]=5,也就说明v1先到v0再到v2的路径比v1直接到v2的路径权值和要小,所以就要更新D矩阵的[1][2]和[2][1]的值为更小的权值和3,同时由于v1到v2需要经过v0,所以P[1][2]=P[2][1]=0  

  2.Floyd算法的C语言代码实现

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "io.h"
  4. #include "math.h"
  5. #include "time.h"
  6.  
  7. #define OK 1
  8. #define ERROR 0
  9. #define TRUE 1
  10. #define FALSE 0
  11. #define MAXEDGE 20
  12. #define MAXVEX 20
  13. #define INFINITY 65535
  14.  
  15. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  16.  
  17. typedef struct
  18. {
  19. int vexs[MAXVEX];
  20. int arc[MAXVEX][MAXVEX];
  21. int numVertexes, numEdges;
  22. }MGraph;
  23.  
  24. typedef int Patharc[MAXVEX][MAXVEX];
  25. typedef int ShortPathTable[MAXVEX][MAXVEX];
  26.  
  27. /* 构件图 */
  28. void CreateMGraph(MGraph *G)
  29. {
  30. int i, j;
  31.  
  32. /* printf("请输入边数和顶点数:"); */
  33. G->numEdges=;
  34. G->numVertexes=;
  35.  
  36. for (i = ; i < G->numVertexes; i++)/* 初始化图 */
  37. {
  38. G->vexs[i]=i;
  39. }
  40.  
  41. for (i = ; i < G->numVertexes; i++)/* 初始化图 */
  42. {
  43. for ( j = ; j < G->numVertexes; j++)
  44. {
  45. if (i==j)
  46. G->arc[i][j]=;
  47. else
  48. G->arc[i][j] = G->arc[j][i] = INFINITY;
  49. }
  50. }
  51.  
  52. G->arc[][]=;
  53. G->arc[][]=;
  54. G->arc[][]=;
  55. G->arc[][]=;
  56. G->arc[][]=;
  57.  
  58. G->arc[][]=;
  59. G->arc[][]=;
  60. G->arc[][]=;
  61. G->arc[][]=;
  62. G->arc[][]=;
  63.  
  64. G->arc[][]=;
  65. G->arc[][]=;
  66. G->arc[][]=;
  67. G->arc[][]=;
  68. G->arc[][]=;
  69.  
  70. G->arc[][]=;
  71.  
  72. for(i = ; i < G->numVertexes; i++)
  73. {
  74. for(j = i; j < G->numVertexes; j++)
  75. {
  76. G->arc[j][i] =G->arc[i][j];
  77. }
  78. }
  79.  
  80. }
  81.  
  82. /* Floyd算法,求网图G中各顶点v到其余顶点w的最短路径P[v][w]及带权长度D[v][w]。 */
  83. void ShortestPath_Floyd(MGraph G, Patharc *P, ShortPathTable *D)
  84. {
  85. int v,w,k;
  86. for(v=; v<G.numVertexes; ++v) /* 初始化D与P */
  87. {
  88. for(w=; w<G.numVertexes; ++w)
  89. {
  90. (*D)[v][w]=G.arc[v][w]; /* D[v][w]值即为对应点间的权值 */
  91. (*P)[v][w]=w; /* 初始化P */
  92. }
  93. }
  94. for(k=; k<G.numVertexes; ++k)
  95. {
  96. for(v=; v<G.numVertexes; ++v)
  97. {
  98. for(w=; w<G.numVertexes; ++w)
  99. {
  100. if ((*D)[v][w]>(*D)[v][k]+(*D)[k][w])
  101. {/* 如果经过下标为k顶点路径比原两点间路径更短 */
  102. (*D)[v][w]=(*D)[v][k]+(*D)[k][w];/* 将当前两点间权值设为更小的一个 */
  103. (*P)[v][w]=(*P)[v][k];/* 路径设置为经过下标为k的顶点 */
  104. }
  105. }
  106. }
  107. }
  108. }
  109.  
  110. int main(void)
  111. {
  112. int v,w,k;
  113. MGraph G;
  114.  
  115. Patharc P;
  116. ShortPathTable D; /* 求某点到其余各点的最短路径 */
  117.  
  118. CreateMGraph(&G);
  119.  
  120. ShortestPath_Floyd(G,&P,&D);
  121.  
  122. printf("各顶点间最短路径如下:\n");
  123. for(v=; v<G.numVertexes; ++v)
  124. {
  125. for(w=v+; w<G.numVertexes; w++)
  126. {
  127. printf("v%d-v%d weight: %d ",v,w,D[v][w]);
  128. k=P[v][w]; /* 获得第一个路径顶点下标 */
  129. printf(" path: %d",v); /* 打印源点 */
  130. while(k!=w) /* 如果路径顶点下标不是终点 */
  131. {
  132. printf(" -> %d",k); /* 打印路径顶点 */
  133. k=P[k][w]; /* 获得下一个路径顶点下标 */
  134. }
  135. printf(" -> %d\n",w); /* 打印终点 */
  136. }
  137. printf("\n");
  138. }
  139.  
  140. printf("最短路径D\n");
  141. for(v=; v<G.numVertexes; ++v)
  142. {
  143. for(w=; w<G.numVertexes; ++w)
  144. {
  145. printf("%d\t",D[v][w]);
  146. }
  147. printf("\n");
  148. }
  149. printf("最短路径P\n");
  150. for(v=; v<G.numVertexes; ++v)
  151. {
  152. for(w=; w<G.numVertexes; ++w)
  153. {
  154. printf("%d ",P[v][w]);
  155. }
  156. printf("\n");
  157. }
  158.  
  159. return ;
  160. }

最短路径算法之Floyd算法

  3.Floyd算法算法的Java语言代码实现

  1. package bigjun.iplab.adjacencyMatrix;
  2.  
  3. public class TheShortestPath_Floyd {
  4.  
  5. private static int[][] D; // 顶点到顶点的最短路径权值和矩阵
  6. private static int[][] P; // 顶点的到顶点的最短路径的前驱矩阵
  7. public final static int INFINITY = Integer.MAX_VALUE;
  8.  
  9. public static void Floyd(AdjacencyMatrixGraphINF G) throws Exception {
  10.  
  11. int v, w ,k;
  12. int vexNum = G.getVexNum();
  13. P = new int[vexNum][vexNum];
  14. D = new int[vexNum][vexNum];
  15. for (v = 0; v < vexNum; v++) {
  16. for (w = 0; w < vexNum; w++) {
  17. D[v][w] = G.getArcs()[v][w]; // 初始化D矩阵为邻接矩阵
  18. P[v][w] = w; // 初始化P矩阵,表示从v到w的最短路径的前驱是w,即直接到达的意思
  19. }
  20. }
  21. for (k = 0; k < vexNum; k++) { // k值表示中转顶点的下标
  22. for (v = 0; v < vexNum; v++) { // v值表示起始顶点的下标
  23. for (w = 0; w < vexNum; w++) { // w值表示终止顶点的下标
  24. if (D[v][k] < INFINITY && D[k][w] < INFINITY && // 注意: 只限定两个不是正无穷就可以,否则会造成越界的情况
  25. D[v][w] > D[v][k] + D[k][w]) { // 从v直接到w的权值和大于从v先到k再到w
  26. D[v][w] = D[v][k] + D[k][w]; // 更新从v到w的权值和
  27. P[v][w] = P[v][k]; // 路径设置为经过下标为k的顶点
  28. }
  29. }
  30. }
  31. }
  32.  
  33. System.out.println("D矩阵为: ");
  34. for (v = 0; v < vexNum; v++) {
  35. for (w = 0; w < vexNum; w++) {
  36. System.out.print(D[v][w] + " ");
  37. }
  38. System.out.println();
  39. }
  40. System.out.println();
  41.  
  42. System.out.println("P矩阵为: ");
  43. for (v = 0; v < vexNum; v++) {
  44. for (w = 0; w < vexNum; w++) {
  45. System.out.print(P[v][w] + " ");
  46. }
  47. System.out.println();
  48. }
  49. System.out.println();
  50.  
  51. System.out.println("各个顶点之间的最短路径的权值和为: ");
  52. for (v = 0; v < vexNum; v++) {
  53. for (w = v + 1; w < vexNum; w++) {
  54. System.out.print(G.getVex(v) + "-");
  55. System.out.print(G.getVex(w) + " weight: ");
  56. System.out.println(D[v][w]);
  57. }
  58. }
  59. System.out.println();
  60.  
  61. System.out.println("各个顶点之间的最短路径为: ");
  62. for (v = 0; v < vexNum; v++) {
  63. for (w = v + 1; w < vexNum; w++) {
  64. System.out.print(G.getVex(v) + "->");
  65. System.out.print(G.getVex(w) + " TheShortestPath: ");
  66. k = P[v][w]; // 获得第一个路径顶点下标
  67. System.out.print(G.getVex(v));
  68. while (k!=w) {
  69. System.out.print("->" + G.getVex(k));
  70. k = P[k][w];
  71. }
  72. System.out.println("->" + G.getVex(w));
  73. }
  74. }
  75. System.out.println();
  76. }
  77. }

  4.Floyd算法执行过程的举例说明

  以下面的图为例:

  

  测试代码为:

  1. // 手动创建一个用于测试最短路径算法的无向网
  2. public static AdjacencyMatrixGraphINF createUDNByYourHand_ForTheShortestPath() {
  3. Object vexs_UDN[] = {"V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8"};
  4. int arcsNum_UDN = 16;
  5. int[][] arcs_UDN = new int[vexs_UDN.length][vexs_UDN.length];
  6. for (int i = 0; i < vexs_UDN.length; i++) // 构造无向图邻接矩阵
  7. for (int j = 0; j < vexs_UDN.length; j++)
  8. if (i==j) {
  9. arcs_UDN[i][j]=0;
  10. } else {
  11. arcs_UDN[i][j] = arcs_UDN[i][j] = INFINITY;
  12. }
  13.  
  14. arcs_UDN[0][1] = 1;
  15. arcs_UDN[0][2] = 5;
  16. arcs_UDN[1][2] = 3;
  17. arcs_UDN[1][3] = 7;
  18. arcs_UDN[1][4] = 5;
  19. arcs_UDN[2][4] = 1;
  20. arcs_UDN[2][5] = 7;
  21. arcs_UDN[3][4] = 2;
  22. arcs_UDN[3][6] = 3;
  23. arcs_UDN[4][5] = 3;
  24. arcs_UDN[4][6] = 6;
  25. arcs_UDN[4][7] = 9;
  26. arcs_UDN[5][7] = 5;
  27. arcs_UDN[6][7] = 2;
  28. arcs_UDN[6][8] = 7;
  29. arcs_UDN[7][8] = 4;
  30.  
  31. for (int i = 0; i < vexs_UDN.length; i++) // 构造无向图邻接矩阵
  32. for (int j = i; j < vexs_UDN.length; j++)
  33. arcs_UDN[j][i] = arcs_UDN[i][j];
  34. return new AdjMatGraph(GraphKind.UDN, vexs_UDN.length, arcsNum_UDN, vexs_UDN, arcs_UDN);
  35. }
  36.  
  37. public static void main(String[] args) throws Exception {
  38.  
  39. AdjMatGraph UDN_Graph_TSP = (AdjMatGraph) createUDNByYourHand_ForTheShortestPath();
  40. TheShortestPath_Floyd.Floyd(UDN_Graph_TSP);
      }

  输出为:

  1. D矩阵为:
  2. 0 1 4 7 5 8 10 12 16
  3. 1 0 3 6 4 7 9 11 15
  4. 4 3 0 3 1 4 6 8 12
  5. 7 6 3 0 2 5 3 5 9
  6. 5 4 1 2 0 3 5 7 11
  7. 8 7 4 5 3 0 7 5 9
  8. 10 9 6 3 5 7 0 2 6
  9. 12 11 8 5 7 5 2 0 4
  10. 16 15 12 9 11 9 6 4 0
  11.  
  12. P矩阵为:
  13. 0 1 1 1 1 1 1 1 1
  14. 0 1 2 2 2 2 2 2 2
  15. 1 1 2 4 4 4 4 4 4
  16. 4 4 4 3 4 4 6 6 6
  17. 2 2 2 3 4 5 3 3 3
  18. 4 4 4 4 4 5 7 7 7
  19. 3 3 3 3 3 7 6 7 7
  20. 6 6 6 6 6 5 6 7 8
  21. 7 7 7 7 7 7 7 7 8
  22.  
  23. 各个顶点之间的最短路径的权值和为:
  24. V0-V1 weight: 1
  25. V0-V2 weight: 4
  26. V0-V3 weight: 7
  27. V0-V4 weight: 5
  28. V0-V5 weight: 8
  29. V0-V6 weight: 10
  30. V0-V7 weight: 12
  31. V0-V8 weight: 16
  32. V1-V2 weight: 3
  33. V1-V3 weight: 6
  34. V1-V4 weight: 4
  35. V1-V5 weight: 7
  36. V1-V6 weight: 9
  37. V1-V7 weight: 11
  38. V1-V8 weight: 15
  39. V2-V3 weight: 3
  40. V2-V4 weight: 1
  41. V2-V5 weight: 4
  42. V2-V6 weight: 6
  43. V2-V7 weight: 8
  44. V2-V8 weight: 12
  45. V3-V4 weight: 2
  46. V3-V5 weight: 5
  47. V3-V6 weight: 3
  48. V3-V7 weight: 5
  49. V3-V8 weight: 9
  50. V4-V5 weight: 3
  51. V4-V6 weight: 5
  52. V4-V7 weight: 7
  53. V4-V8 weight: 11
  54. V5-V6 weight: 7
  55. V5-V7 weight: 5
  56. V5-V8 weight: 9
  57. V6-V7 weight: 2
  58. V6-V8 weight: 6
  59. V7-V8 weight: 4
  60.  
  61. 各个顶点之间的最短路径为:
  62. V0->V1 TheShortestPath: V0->V1
  63. V0->V2 TheShortestPath: V0->V1->V2
  64. V0->V3 TheShortestPath: V0->V1->V2->V4->V3
  65. V0->V4 TheShortestPath: V0->V1->V2->V4
  66. V0->V5 TheShortestPath: V0->V1->V2->V4->V5
  67. V0->V6 TheShortestPath: V0->V1->V2->V4->V3->V6
  68. V0->V7 TheShortestPath: V0->V1->V2->V4->V3->V6->V7
  69. V0->V8 TheShortestPath: V0->V1->V2->V4->V3->V6->V7->V8
  70. V1->V2 TheShortestPath: V1->V2
  71. V1->V3 TheShortestPath: V1->V2->V4->V3
  72. V1->V4 TheShortestPath: V1->V2->V4
  73. V1->V5 TheShortestPath: V1->V2->V4->V5
  74. V1->V6 TheShortestPath: V1->V2->V4->V3->V6
  75. V1->V7 TheShortestPath: V1->V2->V4->V3->V6->V7
  76. V1->V8 TheShortestPath: V1->V2->V4->V3->V6->V7->V8
  77. V2->V3 TheShortestPath: V2->V4->V3
  78. V2->V4 TheShortestPath: V2->V4
  79. V2->V5 TheShortestPath: V2->V4->V5
  80. V2->V6 TheShortestPath: V2->V4->V3->V6
  81. V2->V7 TheShortestPath: V2->V4->V3->V6->V7
  82. V2->V8 TheShortestPath: V2->V4->V3->V6->V7->V8
  83. V3->V4 TheShortestPath: V3->V4
  84. V3->V5 TheShortestPath: V3->V4->V5
  85. V3->V6 TheShortestPath: V3->V6
  86. V3->V7 TheShortestPath: V3->V6->V7
  87. V3->V8 TheShortestPath: V3->V6->V7->V8
  88. V4->V5 TheShortestPath: V4->V5
  89. V4->V6 TheShortestPath: V4->V3->V6
  90. V4->V7 TheShortestPath: V4->V3->V6->V7
  91. V4->V8 TheShortestPath: V4->V3->V6->V7->V8
  92. V5->V6 TheShortestPath: V5->V7->V6
  93. V5->V7 TheShortestPath: V5->V7
  94. V5->V8 TheShortestPath: V5->V7->V8
  95. V6->V7 TheShortestPath: V6->V7
  96. V6->V8 TheShortestPath: V6->V7->V8
  97. V7->V8 TheShortestPath: V7->V8

  结合实例分析代码执行过程:

  

  1. 初始化后的D矩阵和P矩阵如上图所示:当K=0时,所有的顶点都经过v0中转,通过计算可以直到没有最短路径的变化
    K=1时,也就是说所有的顶点都经过v1中转,通过比较
        D02=5 D01+D12=4,所以D02=5P02=1,也就是说v0v2要进过v1
        D03=INF,而D01+D13=8,所以D03=8P03=1
        D04=INF,而D01+D14=6,所以D04=6P04=1
    ...同理
    要求得v0v8的路径,已知最后的P矩阵
    p08=1得知要经过v1,由p18=2得知要经过v2,由p28=4得知要经过v4,由p48=3得知要经过v3,由p38=6得知要经过v6,由p68=7得知要经过v7,由p78=8得知要经过v8
    从而,得出从v0v8要经过的路径为:v0-v1-v2-v4-v3-v6-v7-v8
    其他同理。

数据结构(三十四)最短路径(Dijkstra、Floyd)的更多相关文章

  1. COJ966 WZJ的数据结构(负三十四)

    WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u  ...

  2. NeHe OpenGL教程 第三十四课:地形

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. JAVA之旅(三十四)——自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫

    JAVA之旅(三十四)--自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫 我们接着来说网络编程,TCP 一.自定义服务端 我们直接写一个服务端,让本机去连接 ...

  4. Java进阶(三十四)Integer与int的种种比较你知道多少?

    Java进阶(三十四)Integer与int的种种比较你知道多少? 前言 如果面试官问Integer与int的区别:估计大多数人只会说到两点:Ingeter是int的包装类,注意是一个类:int的初值 ...

  5. Gradle 1.12用户指南翻译——第三十四章. JaCoCo 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  6. SQL注入之Sqli-labs系列第三十四关(基于宽字符逃逸POST注入)和三十五关

    开始挑战第三十四关和第三十五关(Bypass add addslashes) 0x1查看源码 本关是post型的注入漏洞,同样的也是将post过来的内容进行了 ' \ 的处理. if(isset($_ ...

  7. spring boot 常见三十四问

    Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家. 问题一 Spring Boot.Spring MVC 和 Spring 有什么区别 ...

  8. “全栈2019”Java多线程第三十四章:超时自动唤醒被等待的线程

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. 第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息

    第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息 crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多 ...

  10. “全栈2019”Java第三十四章:可变参数列表

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. 暑期——第五周总结(Web连接hbase数据库)

    所花时间:7天 代码行:1000(python)+250(java) 博客量:1篇 了解到知识点 : 在尝试使用hbase当作数据库时,林子雨老师教程中有完整代码关于使用hbase,我就像当然认为只需 ...

  2. linux初学者小记

    a开头的小命令 alias命令 # echo=' - - - ' > /sys/class/scsi_host/host0/scan这条命令是咱们在给虚拟机装了一块新的硬盘后,在不关机的前提下扫 ...

  3. Save&Load--Unity存档读档的学习总结

    存档与读档功能 举例: 传统RPG游戏(仙剑.空之轨迹): 1.角色信息(生命值,等级) 2.道具信息(装备,药品) 3.场景信息(场景名称.角色坐标) 4.事件信息(任务相关) 关卡类游戏:关卡的通 ...

  4. git clone 解决Permission Denied (publickey)问题

    本地git bash 使用git clone git@github.com:***.git方式下载github代码至本地时需要依赖ssh key,遇到权限不足问题时一般都是SSH key失效或者SSH ...

  5. 3. Git与TortoiseGit基本操作

    1. GitHub操作 本节先简单介绍 git 的使用与操作, 然后再介绍 TortoiseGit 的使用与操作. 先看看SVN的操作吧, 最常见的是 检出(Check out ...), 更新 (U ...

  6. export import 的用法和注意之处

       1.整体引入: 会将若干export导出的内容组合成一个对象返回: import *as  api from  utils.https; api为自定义名称,可直接指定此文件中的某个方法,uti ...

  7. Spark 学习笔记之 aggregateByKey

    aggregateByKey: import org.apache.spark.SparkContext import org.apache.spark.rdd.RDD import org.apac ...

  8. docker服务在Mac上的启动与使用

    在mac上打开安装的docker软件就可以启动docker服务了 点击顶部状态栏中鲸鱼图标会弹出操作菜单,显示着服务的状态,如下图所示: 只有在docker服务启动了之后,才可以在终端使用docker ...

  9. python-setup模块

    本地打包,setup安装 一.distutils 使用:distutils 进行打包,步骤如下,以单一文件为例. 1.创建文件 在同一目录下.写一个foo.py文件: #-*- coding:utf- ...

  10. 云上的芯脏病:奇怪的阿里云 RDS 数据库突发 CPU 近 100% 问题

    最近遇到了奇怪的阿里云 RDS 数据库突发 CPU 近 100% 问题,遇到了3次. 第一次是10月12日(周六)凌晨 3:24 负载极低的时候开始出现,早上发现后进行了主备切换,恢复了正常. 第二次 ...