• 最短路径专题6 最短路径-多路径


    题目:

    样例:

    输入
    1. 4 5 0 2
    2. 0 1 2
    3. 0 2 5
    4. 0 3 1
    5. 1 2 1
    6. 3 2 2

    输出
    1. 2
    2. 0->1->2
    3. 0->3->2

    思路:

            根据题意,最短路模板还是少不了的,

    我们要添加的是,

    记录各个结点有多少个上一个结点走动得来的,由于更新了最短路径,需要清空之前的记录的结点,重新记录当前结点由哪上一个结点得来的;

    当遇到相同的最短路距离的时候,直接添加 j 结点也由 当前结点得来的。

    最后递归遍历各个结点路径,并存储好,输出即可。

    代码详解如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define endl '\n'
    7. #define x first
    8. #define y second
    9. #define mk make_pair
    10. #define int long long
    11. #define NO puts("NO")
    12. #define YES puts("YES")
    13. #define umap unordered_map
    14. #define INF 0x3f3f3f3f3f3f3f3f
    15. #define All(x) (x).begin(),(x).end()
    16. #pragma GCC optimize(3,"Ofast","inline")
    17. #define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
    18. using namespace std;
    19. const int N = 2e6 + 10;
    20. using PII = pair<int,int>;
    21. int n,k,start,last;
    22. int dist[N];
    23. bool st[N];
    24. // 建立链表
    25. int h[N],e[N],w[N],ne[N],idx;
    26. inline void Add(int a,int b,int c)
    27. {
    28. e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx++;
    29. }
    30. vector<int>tree[N]; // 记录每个结点拥有哪些结点得来的
    31. inline void Dijkstra()
    32. {
    33. memset(dist,INF,sizeof dist);
    34. dist[start] = 0;
    35. priority_queue,greater>q;
    36. q.push(mk(0,start));
    37. while(q.size())
    38. {
    39. PII now = q.top();
    40. q.pop();
    41. int a = now.y;
    42. int dis = now.x;
    43. if(st[a]) continue;
    44. st[a] = true;
    45. for(int i = h[a];i != -1;i = ne[i])
    46. {
    47. int j = e[i];
    48. if(dist[j] > dis + w[i])
    49. {
    50. dist[j] = dis + w[i];
    51. tree[j].clear(); // 更新了最短路径,所以清空上一个结点记录过的多个结点 路径
    52. tree[j].emplace_back(a); // j 结点记录 添加 a 结点得来的路径
    53. }else // 如果遇到相同最短路距离,j 结点 添加 当前的 a 结点路径
    54. if(dist[j] == dis + w[i]) tree[j].emplace_back(a);
    55. // 记录该结点,方便下一次的走动
    56. q.push(mk(dist[j],j));
    57. }
    58. }
    59. return ;
    60. }
    61. vectorint>>paths; // 记录多个路径
    62. vector<int>tempPath; // 临时路径
    63. void getPath(int now)
    64. {
    65. // 到达递归边界,开始回溯取各个路径
    66. if(now == start)
    67. {
    68. tempPath.emplace_back(now); // 临时路径存储当前结点
    69. paths.emplace_back(tempPath); // 存储路径
    70. tempPath.pop_back(); // 弹出存储的当前结点,进行回溯,寻找另一条不同的路径
    71. return ;
    72. }
    73. tempPath.emplace_back(now); // 临时路径存储当前结点
    74. // 遍历 当前结点 now 由哪个结点得来的
    75. // 递归获取路径结点
    76. for(auto i : tree[now])
    77. {
    78. getPath(i);
    79. }
    80. tempPath.pop_back(); // 弹出存储的当前结点,进行回溯,寻找另一条不同的路径
    81. return ;
    82. }
    83. inline void solve()
    84. {
    85. // 初始化链表
    86. memset(h,-1,sizeof h);
    87. cin >> n >> k >> start >> last;
    88. while(k--)
    89. {
    90. int a,b,c;
    91. cin >> a >> b >> c;
    92. Add(a,b,c);
    93. Add(b,a,c);
    94. }
    95. // 求最短路径
    96. Dijkstra();
    97. // 获取最短路径
    98. getPath(last);
    99. int sum = paths.size(); // 总的路径数量
    100. // 翻转获得的全部路径,由于我们是从终点往后获取的
    101. // 所以需要翻转一下
    102. for(int i = 0;i < sum;++i)
    103. {
    104. reverse(All(paths[i]));
    105. }
    106. // 根据题意,字典序排序好每条路径
    107. sort(All(paths));
    108. // 输出路径条数
    109. cout << sum << endl;
    110. // 输出记录的每条最短路路径
    111. for(int i = 0;i < sum;++i)
    112. {
    113. bool rem = false; // 控制格式
    114. for(int j : paths[i])
    115. {
    116. if(rem) cout << "->";
    117. cout << j;
    118. rem = true;
    119. }
    120. cout << endl;
    121. }
    122. }
    123. signed main()
    124. {
    125. // freopen("a.txt", "r", stdin);
    126. ___G;
    127. int _t = 1;
    128. // cin >> _t;
    129. while (_t--)
    130. {
    131. solve();
    132. }
    133. return 0;
    134. }

    最后提交:

  • 相关阅读:
    第七十天学习记录:高等数学:微分(宋浩板书)
    使用Python爬取信息403解决,并统计汇总绘制直方图,柱状图,折线图
    华为三层交换机与路由器对接上网
    CentOS 7.6上安装RabbitMQ
    04-Vue的简单动画Transition,动画钩子函数,Animate第三方动画库,TransitionGroup列表动画
    Cesium
    02 项目设置
    命令模式【Java设计模式】
    企业微信应用开发
    Oracle 19c RAC installation on centos7.5
  • 原文地址:https://blog.csdn.net/hacker_51/article/details/133588323