zoukankan      html  css  js  c++  java
  • Dijkstra模板(最短路径)

    1. /***********************************************************************************************
    2. 注意相应权值不能为负,且时间复杂度较高
    3. 算法步骤如下:
    4. 1. 初始时令 S={V0},T={其余顶点},T中顶点对应的距离值
    5. 若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值
    6. 若不存在<V0,Vi>,d(V0,Vi)为∞
    7. 2. 从T中选取一个其距离值为最小的顶点W且不在S中,加入S
    8. 3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值
    9. 重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止
    10. ************************************************************************************************/
    11. #include <stdio.h>
    12. #define INF 0x7fffffff
    13. #define MAX 1100
    14. int dist[MAX], pre[MAX], path[MAX][MAX];
    15. bool sign[MAX];
    16. void initialize(int n) //初始化
    17. {
    18. for(int i=1; i<=n; i++)
    19. {
    20. {
    21. //pre[i] = 0;
    22. dist[i] = INF; //将距离开始全变为最大
    23. //sign[i] = false;
    24. }
    25. for(int j=1; j<=n; j++)
    26. path[i][j] = INF; //图初始
    27. }
    28. }
    29. void dijkstra(int n, int source )
    30. {
    31. for(int i=1; i<=n; i++)
    32. {
    33. dist[i] = path[source][i]; //将与源点有关的点的距离加入dist
    34. sign[i] = false;
    35. if(dist[i] == INF) //确定有关系的点的前驱,无则为0
    36. pre[i] = 0;
    37. else
    38. pre[i] = source;
    39. }
    40. dist[source] = 0; //源点自身长度为0
    41. sign[source] = 1;
    42. /*
    43. 依次将未放入sign集合的结点中,取dist[]最小值的结点,放入结合sign中
    44. 一旦sign包含了所有n中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
    45. */
    46. for(int i=2; i<=n; i++)
    47. {
    48. int min = INF;
    49. int current = source;
    50. for(int j=1; j<=n; j++) //找出当前未使用点j的dist[j]的最小值
    51. {
    52. if( (!sign[j]) && dist[j] < min )
    53. {current = j; min = dist[j];}
    54. }
    55. sign[current] = true; //表示当前点最短距离已经找到
    56. for(int j=1; j<=n; j++) //更新当前点到未找到点的距离
    57. if( (!sign[j]) && path[current][j] < INF)
    58. {
    59. int newdist = dist[current] + path[current][j];
    60. if(newdist < dist[j] )
    61. {dist[j] = newdist; pre[j] = current;}
    62. }
    63. }
    64. }
    65. void search_path(int n, int start, int end)
    66. {
    67. int road[MAX];
    68. int total = 1;
    69. road[total++] = end; //从后向前查找
    70. int current = pre[end]; //路径存在pre中
    71. while( current != start) //递归查找,类似并查集
    72. {
    73. road[total++] = current;
    74. current = pre[current];
    75. }
    76. road[total] = start; //最后的开始点存入
    77. for(int i=total; i>=1; i--) //输出
    78. {
    79. if( i!=1)
    80. printf("%d ->", road[i]);
    81. else
    82. printf("%d ", road[i]);
    83. }
    84. }
    85. void input(int line)
    86. {
    87. int a, b, weight;
    88. for(int i=0; i<line; i++)
    89. {
    90. scanf("%d%d%d", &a, &b, &weight);
    91. if(path[a][b] > weight) //有多条路,保存最短的那条
    92. {
    93. path[a][b] = weight;
    94. path[b][a] = weight; //无向图双向
    95. }
    96. }
    97. }
    98. int main()
    99. {
    100. int n, line;
    101. scanf("%d%d", &n, &line);
    102. initialize(n);
    103. input(line);
    104. dijkstra(n, 1);
    105. printf("%d ", dist[n]);
    106. search_path(n, 1, n);
    107. return 0;
    108. }





    附件列表

    • 相关阅读:
      范畴定义
      泛函编程(0)-什么是泛函编程
      函数式语言的特性
      理解函数式编程
      未阅归档
      monad-本质解释- a monad is a design pattern--monad与泛型相关
      打印管理系统
      函数式JS: 原来promise是这样的monad
      Promise是Monad吗?
      Scala和范畴论 -- 对Monad的一点认识
    • 原文地址:https://www.cnblogs.com/sober-reflection/p/dd93eb9aa504968a466fcda4df410338.html
    Copyright © 2011-2022 走看看