题意

给定一张 \(N\) 个点(编号 \(1,2…N\)),\(M\) 条边的有向图,求从起点 \(S\) 到终点 \(T\) 的第 \(K\) 短路的长度,路径允许重复经过点或边。

注意: 每条最短路中至少要包含一条边。

由于直接\(BFS\)搜索空间特别大,所以考虑\(A*\)算法

  1. 以从\(x\)点到终点的最短距离为估价函数,那么这个可以通过反向求终点到\(x\)的单源最短距离实现。

  2. 当终点\(T\), 第\(K\)次被拓展的时候,就得到了\(S\)到\(T\)的第\(K\)短路。

  1. // Problem: 第K短路
  2. // Contest: AcWing
  3. // URL: https://www.acwing.com/problem/content/180/
  4. // Memory Limit: 64 MB
  5. // Time Limit: 1000 ms
  6. //
  7. // Powered by CP Editor (https://cpeditor.org)
  8. #include <bits/stdc++.h>
  9. using namespace std;
  10. typedef pair<int, int> PII;
  11. typedef pair<int, pair<int, int>> PIII;
  12. const int N = 1010, M = 200010;
  13. int h[N], rh[N], e[M], ne[M], w[M], idx;
  14. int S, T, K, n, m;
  15. int dist[N];
  16. bool st[N];
  17. int cnt[N];
  18. void add(int h[], int a, int b, int c) {
  19. e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
  20. }
  21. void Dijkstra() {
  22. priority_queue<PII, vector<PII>, greater<PII>> heap;
  23. memset(dist, 0x3f, sizeof dist);
  24. dist[T] = 0;
  25. heap.push({0, T});
  26. while (heap.size()) {
  27. auto t = heap.top();
  28. heap.pop();
  29. int ver = t.second;
  30. if (st[ver]) continue;
  31. st[ver] = true;
  32. for (int i = rh[ver]; i != -1; i = ne[i]) {
  33. int j = e[i];
  34. if (dist[j] > dist[ver] + w[i]) {
  35. dist[j] = dist[ver] + w[i];
  36. heap.push({dist[j], j});
  37. }
  38. }
  39. }
  40. }
  41. int astar() {
  42. priority_queue<PIII, vector<PIII>, greater<PIII>> heap;
  43. heap.push({dist[S], {0, S}});
  44. while (heap.size()) {
  45. auto t = heap.top();
  46. heap.pop();
  47. int ver = t.second.second, distance = t.second.first;
  48. cnt[ver]++;
  49. if (cnt[T] == K) return distance;
  50. for (int i = h[ver]; i != -1; i = ne[i]) {
  51. int j = e[i];
  52. if (cnt[j] < K) {
  53. heap.push({distance + w[i] + dist[j], {distance + w[i], j}});
  54. }
  55. }
  56. }
  57. return -1;
  58. }
  59. int main() {
  60. ios::sync_with_stdio(false);
  61. cin.tie(0);
  62. cin >> n >> m;
  63. memset(h, -1, sizeof h);
  64. memset(rh, -1, sizeof rh);
  65. for (int i = 0; i < m; i++) {
  66. int a, b, c;
  67. cin >> a >> b >> c;
  68. add(h, a, b, c), add(rh, b, a, c);
  69. }
  70. cin >> S >> T >> K;
  71. if (S == T) K++; //因为最少要经过一条边,当S, T一个点输出0,所以我们先K++
  72. Dijkstra();
  73. cout << astar() << endl;
  74. return 0;
  75. }

AcWing 178. 第K短路的更多相关文章

  1. AcWing:178. 第K短路(A*)

    给定一张N个点(编号1,2…N),M条边的有向图,求从起点S到终点T的第K短路的长度,路径允许重复经过点或边. 注意: 每条最短路中至少要包含一条边. 输入格式 第一行包含两个整数N和M. 接下来M行 ...

  2. POJ 2449 Remmarguts' Date --K短路

    题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...

  3. POJ 2449Remmarguts' Date K短路模板 SPFA+A*

    K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...

  4. BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...

  5. 【POJ】2449 Remmarguts' Date(k短路)

    http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...

  6. poj 2449 Remmarguts' Date K短路+A*

    题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...

  7. 第k短路

    poj 2449 模板题  A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  8. poj 2449(A*求第K短路)

    题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...

  9. K短路

    K短路 用dijsktra+A*启发式搜索当点v第K次出堆的时候,这时候求得的路径是k短路.A*算法有一个启发式函数f(p)=g(p)+h(p), 即评估函数=当前值+当前位置到终点的最短距离g(p) ...

  10. poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)

    http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

随机推荐

  1. pandas 缺失值与空值处理

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/lwgkzl/article/detail ...

  2. 69.9K Star,最强开源内网穿透工具:frp

    作为一名开发者,有很多场景需要用到内网穿透,比如:我们在接入一些大平台做第三方应用时,在本地开发微信公众号工具的时候需要让微信平台能否访问到本地提供的接口.除此之外,还有很多其他场景,也会用到,比如: ...

  3. 牛客小白月赛64 C题 题解

    题目链接 题意描述 这一题的意思其实就是,让你构造一个\(n * k\)的矩阵,使得第 i 列的总和为 i ,同时使得:每一列的任意两个数之间的差不大于1,且任意两行之间的总和差不大于1. \(1 \ ...

  4. 这样拆分和压缩css代码

    在[拆分]和[压缩]css代码之前,首先要配置 loader 处理不同的 css 资源,因为 webpack 没有默认可处理 css 资源的规则,具体可参考这一篇 webpack处理css/less资 ...

  5. Vue3 vite:is a JavaScript file. Did you mean to enable the 'allowJs' option?

    描述 今天在vue3+vite下进行打包时,突然vscode报了一个error. 大概的意识是询问是否启用"allowJS"选项,因为该文件在程序内是指定用于编译的根文件. 提示信 ...

  6. Auto-GPT免费尝鲜之初体验-使用攻略和总结

    写在前面的废话 ChatGPT 的交互模式,是和一个 "人" 对话聊天. 如果你想了解更多ChatGPT和AI绘画的相关知识,请参考:ChatGPT注册和变现思路,AI绘画教程汇总 ...

  7. 标题:在Godot中使用Node2D创建自定义的Label

    在Godot游戏引擎中,我们经常需要在游戏中显示文本信息.通常,我们可以使用Label节点来实现这一点.但是,在某些情况下,你可能希望更灵活地控制文本的显示和样式.在本篇博客中,我们将学习如何通过使用 ...

  8. 《CTFshow-Web入门》04. Web 31~40

    @ 目录 web31 题解 原理 web32 题解 原理 web33 题解 web34 题解 web35 题解 web36 题解 web37 题解 原理 web38 题解 原理 web39 题解 we ...

  9. 《Python魔法大冒险》010 魔法宝箱:列表与元组的探险

    城堡的大门 随着小鱼和魔法师的深入,他们来到了一个古老的废弃城堡.城堡的大门上挂着一个巨大的锁,而锁的旁边有一排小抽屉,每个抽屉里都有一个物品. 魔法师对小鱼说:"这是一个古老的魔法宝箱,小 ...

  10. linux上搭建Nacos集群(步骤详细,linux小白也能搞定)

    (1)nacos官网:https://github.com/alibaba/nacos/releases/tag/1.2.1下载nacos安装包到window本地(后缀为tar.zip) (2)在li ...