称号:poj 2449 Remmarguts' Date

意甲冠军:给定一个图,乞讨k短路。

算法:SPFA求最短路 + AStar

以下引用大牛的分析:

首先,为了说话方便,列出一些术语:

启示式搜索中,对于每一个状态 x。启示函数 f(x) 一般是这种形式:

f(x) = g(x) + h(x)

当中 g(x) 是从初始状态走到 x 所花的代价;h(x)
是从 x 走到目标状态所须要的代价的预计值。

相对于 h(x)。另一个概念叫 h*(x),表示从 x 走到目标状态所须要的实际最小代价(当然,这个值有时我们是事先无法知道的)。

假设在你的启示函数里,能保证 h(x) <= h*(x)。也就是说,你不能高估了从 x 走到目标状态所须要的代价,那就能够说这个搜索是 A* 算法(这里的“*”,英文就读作 star)。

A* 算法的特点是,假设存在从初始状态走到目标状态的最小代价的解。那么用 A* 算法搜索时,第一个找到的解就一定是最小代价的。这就是所谓的可採纳(admissible)。

1. 求前 K 短的 能够带环的 路径(的长度)

1.1. 典型的启示式搜索

设起点为 s;终点为 t。对于一个点 v,dt(v) 表示从 v 走到 t 的最短路径的长度(能够在初始化的时候全都算好)。

能够用最典型的启示式搜索来解这个问题。

一个状态 x 表示的是从 s 走到某个点的一条路径。把这个点记作 x.v,把这条路径的长度记作 x.len。接着。我们能够使用下面启示函数:

g(x) = x.len;  h(x) = dt(x.v);

∴ f(x) = g(x) + h(x) = x.len + dt(x.v)

初始状态中。 x.v = s; x.len
= 0。

然后每次让优先队列(所谓的 Open
表)中 f(x) 值最小的状态 x
出队,再跟据图中全部从 x.v 出发的边发展下一层状态,让它们进队列。优先队列中不存在判反复的问题,由于每一个状态所代表的路径肯定是不一样的。

不难想通,这是一个 A* 算法。由于这里的 h(x) 本身就是 h*(x),当然满足 h(x) <= h*(x)。

因此能够说,在每次出队列的状态 x 中,第一次遇到 x.v == t 时。就找到了从 s 到 t 的第一短的路径,它的长度就是 f(x)……第 k 次遇到 x.v == t 时,就找到了从 s 到 t 的第 k 短的路径。

这就是传说中的启示式搜索,由于有启示函数,并且可以利用广搜的特性,不断的扩展。

感觉是一个非常经典的题目。

注意的是,假如起点和终点是同一点,由于第一次走到的就是,所以必须K++

继续膜拜大牛,上我写的挫代码:

  1. #include <cstdio>
  2. #include <string>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <queue>
  8. using namespace std;
  9. const int N = 1200;
  10. const int inf = 0x3f3f3f3f;
  11. struct Node
  12. {
  13. int to,val;
  14. };
  15. vector<Node> g[N],rg[N];
  16. int dis[N];
  17. bool vis[N];
  18. int n,m;
  19. void SPFA(int src)
  20. {
  21. int i;
  22. memset(dis,inf,sizeof(dis));
  23. dis[src] = 0;
  24. queue<int> Q;
  25. Q.push(src);
  26. while(!Q.empty())
  27. {
  28. int u,v;
  29. u = Q.front();
  30. Q.pop();
  31. for(int i = 0;i<g[u].size();i++)
  32. {
  33. v = g[u][i].to;
  34. if(dis[v]>dis[u]+g[u][i].val) //记得这里这样写 最后改一下vis
  35. {
  36. dis[v] = dis[u] + g[u][i].val;
  37. Q.push(v);
  38. }
  39. }
  40. }
  41. }
  42. struct Tree
  43. {
  44. int v,len,h;
  45. bool operator < (const Tree & a) const
  46. {
  47. return a.h<h;
  48. }
  49. };
  50. priority_queue<Tree> que;
  51. int Astar(int s,int t,int k)
  52. {
  53. int cnt = 0;
  54. while(!que.empty())
  55. que.pop();
  56. if(s==t)
  57. k++;
  58. if(dis[s]==inf)
  59. return -1;
  60. Tree no,next;
  61. no = (Tree){s,0,dis[s]};
  62. que.push(no);
  63. while(!que.empty())
  64. {
  65. no = que.top();
  66. que.pop();
  67. //printf("%d %d %d \n",no.v,no.len,no.h);
  68. if(no.v == t)
  69. cnt++;
  70. if(cnt==k)
  71. return no.len;
  72. for(int i=0;i<rg[no.v].size();i++)
  73. {
  74. Node tmp = rg[no.v][i];
  75. next.v = tmp.to;
  76. next.len = no.len + tmp.val;
  77. next.h = next.len + dis[tmp.to];
  78. que.push(next);
  79. }
  80. }
  81. return -1;
  82. }
  83. void Clear(int x)
  84. {
  85. for(int i=0;i<=x;i++){
  86. g[i].clear();
  87. rg[i].clear();
  88. }
  89. }
  90. int main()
  91. {
  92. //freopen("Input.txt","r",stdin);
  93. while(~scanf("%d%d",&n,&m))
  94. {
  95. for(int i=0;i<m;i++)
  96. {
  97. int x,y,z;
  98. scanf("%d%d%d",&x,&y,&z);
  99. g[y].push_back((Node){x,z});
  100. rg[x].push_back((Node){y,z});
  101. }
  102. int s,t,k;
  103. scanf("%d%d%d",&s,&t,&k);
  104. SPFA(t);
  105. int ans = Astar(s,t,k);
  106. printf("%d\n",ans);
  107. Clear(n);
  108. }
  109. return 0;
  110. }

版权声明:本文博主原创文章,博客,未经同意,不得转载。

poj 2449 Remmarguts&#39; Date 【SPFA+Astar】【古典】的更多相关文章

  1. poj 2449 Remmarguts' Date (k短路模板)

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

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

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

  3. POJ——2449 Remmarguts' Date

    Description "Good man never makes girls wait or breaks an appointment!" said the mandarin ...

  4. poj 2449 Remmarguts' Date 求第k短路 Astar算法

    =.=好菜 #include <iostream> #include <cstdio> #include <string.h> #include <cstri ...

  5. POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang

    题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 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. 图论(A*算法,K短路) :POJ 2449 Remmarguts' Date

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 ...

  8. poj 2449 Remmarguts' Date 第k短路 (最短路变形)

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 33606   Accepted: 9116 ...

  9. POJ 2449 Remmarguts' Date

    Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30725   Accepted: 8389 Description &quo ...

随机推荐

  1. 【SICP读书笔记(五)】练习2.32 --- 递归求集合子集

    题目内容: 我们可以将一个集合表示为一个元素互不相同的表,因此就可以将一个集合的所有子集表示为表的表.例如,假定集合为(1,2,3),它的所有子集的集合就是( () (3) (2) (2 3) (1) ...

  2. 【SICP读书笔记(三)】练习2.18 --- 表序列的reverse方法

    来自练习2.18 请定义出过程reverse,它以一个表为参数,返回的表中所包含的元素与参数表相同,但排列顺序与参数表相反: (reverse (list 1 4 9 16 25)) (25 16 9 ...

  3. 【翻译自mos文章】回收 asm磁盘空间的方法

    回收 asm磁盘空间的方法 參考原文: How To Reclaim Asm Disk Space? (Doc ID 351866.1) 适用于: Oracle Database - Enterpri ...

  4. 表的顺序结构---重写Arraylist类

    重写ArrayList类,为防止冲突,重写为MyArrayList,未继承Iterable类. public class MyArrayList<AnyType>{ int N=10; A ...

  5. Best Time to Buy and Sell Stock I,II,III [leetcode]

    Best Time to Buy and Sell Stock I 你只能一个操作:维修preMin拍摄前最少发生值 代码例如以下: int maxProfit(vector<int> & ...

  6. 旧Mj下拉刷新 An instance 0xca90200 of class UITableView was deallocated while key value observers were s

    An instance 0xca90200 of class UITableView was deallocated while key value observers were still regi ...

  7. pyspark简要原则

    概要 这是一个看前一段时间spark的python支持的时,有点简单的后pyspark内python代码,我们把一个一般流程.虽然几乎没有python,但基本上能看懂pyspark它是如何使不同的虚拟 ...

  8. C#使用xpath找到一个节点

    Xpath这是非常强大.但对比是一个更复杂的技术,希望上面去博客园特别想看看一些专业职位.下面是一些简单Xpath的语法和示例,给你参考 <?xml version="1.0" ...

  9. 第十二章——SQLServer统计信息(2)——非索引键上统计信息的影响

    原文:第十二章--SQLServer统计信息(2)--非索引键上统计信息的影响 前言: 索引对性能方面总是扮演着一个重要的角色,实际上,查询优化器首先检查谓词上的统计信息,然后才决定用什么索引.一般情 ...

  10. oracle 创建字段自增长——两种实现方式汇总(转)

    mysql等其他数据库中有随着记录的插入而表ID自动增长的功能,而oracle却没有这样的功能,我们有以下两种方式可以解决字段自增长的功能. 因为两种方式都需要通过创建序列来实现,这里先给出序列的创建 ...