• UVA-1599 理想路径 题解答案代码 算法竞赛入门经典第二版


    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版

    本题目是在普通最短路的基础上,加上了路径标识(颜色),根据路径标识做进一步筛选。

    我使用了两次BFS完成这道题目:

    第一次是遍历整个图,标注出每个节点到终点的距离。实际上是为了给第二次遍历缩小范围。

    这一次遍历实际上就已经得到了不包含路径标识(颜色信息)的最短路径

    第二次是根据上一次遍历得到的最短路径结果,根据颜色信息筛选出符合要求的最短路。

    这个题目还有几点需要注意:

    题目结点数据量太大,直接用邻接矩阵无法存储,可以使用邻接表。

    遍历的时候注意减少不必要的遍历情况,比如那些确定不是最短路的路径结点不能再加入队列,队列中也不要有重复的结点。

    由于邻接表查找某条路径耗时较多,因此第二次遍历时可以存储下当前最短路径的颜色信息。

    AC代码

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define MAXN 100002
    7. using namespace std;
    8. struct Edge {
    9. int b, c;
    10. };
    11. vector ve[MAXN];
    12. int flagEnd[MAXN];
    13. int flagFront[MAXN];
    14. int pathFront[MAXN];
    15. int path[MAXN];
    16. int n;
    17. void clear() {
    18. memset(flagEnd, 0, sizeof(flagEnd));
    19. memset(flagFront, 0, sizeof(flagFront));
    20. memset(pathFront, 0, sizeof(pathFront));
    21. memset(path, 0, sizeof(path));
    22. fill(ve, ve + MAXN, vector());
    23. }
    24. void bfsEnd() {
    25. int i, j;
    26. queue<int> qu;
    27. qu.push(n);
    28. flagEnd[n] = 1;
    29. while(!qu.empty()) {
    30. i = qu.front();
    31. qu.pop();
    32. for(j = 0; j < ve[i].size(); ++j) {
    33. if(!flagEnd[ve[i][j].b]) {
    34. flagEnd[ve[i][j].b] = flagEnd[i] + 1;
    35. qu.push(ve[i][j].b);
    36. }
    37. }
    38. }
    39. }
    40. void bfsBeg() {
    41. int i, j, k, f;
    42. flagFront[1] = 0;
    43. pathFront[1] = 0;
    44. queue<int> qu;
    45. qu.push(1);
    46. while(!qu.empty()) {
    47. i = qu.front();
    48. qu.pop();
    49. f = 1000000001;
    50. for(j = 0; j < ve[i].size(); ++j) {
    51. k = ve[i][j].b;
    52. if(flagEnd[k] != flagEnd[i] - 1) continue;
    53. if(ve[i][j].c >= f) continue;
    54. f = ve[i][j].c;
    55. if(flagFront[k] && pathFront[k] < f) {
    56. f = pathFront[k];
    57. }
    58. }
    59. for(j = 0; j < ve[i].size(); ++j) {
    60. k = ve[i][j].b;
    61. if(ve[i][j].c != f || flagEnd[k] != flagEnd[i] - 1) continue;
    62. if(flagFront[k] && pathFront[k] > f || !flagFront[k]) {
    63. qu.push(k);
    64. flagFront[k] = i;
    65. pathFront[k] = f;
    66. }
    67. }
    68. }
    69. }
    70. int getPath() {
    71. int i = n, j = 0;
    72. while(flagFront[i]) {
    73. path[j] = pathFront[i];
    74. i = flagFront[i];
    75. ++j;
    76. }
    77. return j;
    78. }
    79. void input(int m) {
    80. int a, b, c;
    81. for(int i = 0; i < m; ++i) {
    82. scanf("%d %d %d", &a, &b, &c);
    83. if(a == b) continue;
    84. ve[a].push_back({b, c});
    85. ve[b].push_back({a, c});
    86. }
    87. }
    88. int main() {
    89. int m, i, j, k;
    90. int a, b, c;
    91. while(scanf("%d %d", &n, &m) == 2) {
    92. clear();
    93. input(m);
    94. bfsEnd();
    95. bfsBeg();
    96. j = getPath();
    97. printf("%d\n", j);
    98. for(i = j - 1; i >= 0; --i) {
    99. if(i != j - 1) {
    100. putchar(' ');
    101. }
    102. printf("%d", path[i]);
    103. }
    104. putchar('\n');
    105. }
    106. return 0;
    107. }

  • 相关阅读:
    2020CCPC 秦皇岛站 个人题解
    Qwen-VL:多功能视觉语言模型,能理解、能定位、能阅读等
    OpenCV自学笔记十二:形态操作(二)
    行列式展开:行列式等于它的任一行(列)的元素与其对应的代数余子式的乘积之和
    解决:brew install xxx 时出现“No such file or directory @ rb_sysopen - ”
    MySQL常用脚本
    最长公共子序列(冬季每日一题 5)
    让环境自己说话,论环境自描述的重要性
    cgal + sfcgal
    nginx重写与防盗链
  • 原文地址:https://blog.csdn.net/qq278672818/article/details/126572811