A*算法求第k短路流程:

1)计算h[],即当前点到t的估计值

  若为有向图,建立反向图求出h[]。若为无向图,可直接求解h[]。可通过SPFA求解。

2)A*搜索

  每次找到新节点就直接加入队列,计算出估价函数f[]=g[]+h[],然后加入优先队列中。(此步不可优化,否则可能造成失解)

  常用STL priority_queue实现,要注意默认是大根堆,可重载<实现小根堆。

3)若根入队k次,返回

ADD:

该题几个注意事项及优化:

  a)若起始点h值==INF,不搜。

  b)若一个点入队超过k次,不搜。

  c)邻接表代替邻接矩阵,防止重边。

  d)该题中若s==t,距离为0的路径不能计入。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <utility>
  8. #include <vector>
  9. #include <queue>
  10. #include <map>
  11. #include <set>
  12. #define max(x,y) ((x)>(y)?(x):(y))
  13. #define min(x,y) ((x)>(y)?(y):(x))
  14. #define INF 0x3f3f3f3f
  15. #define N 1005
  16. #define M 100005
  17.  
  18. using namespace std;
  19.  
  20. struct Edge
  21. {
  22. int y,w,ne;
  23. }e[M*],re[M*];
  24.  
  25. int x,y,w,n,m,s,t,k;
  26. int be[N],all;
  27. int rbe[N],rall;
  28. int h[N],cnt[N];
  29. bool vis[N];
  30.  
  31. struct Point
  32. {
  33. int x,g;
  34. bool operator < (const Point T) const
  35. {
  36. return g+h[x]>T.g+h[T.x];
  37. }
  38. };
  39.  
  40. void add(int x, int y, int w)
  41. {
  42. e[all].y=y;
  43. e[all].w=w;
  44. e[all].ne=be[x];
  45. be[x]=all++;
  46. }
  47. void radd(int x, int y, int w)
  48. {
  49. re[rall].y=y;
  50. re[rall].w=w;
  51. re[rall].ne=rbe[x];
  52. rbe[x]=rall++;
  53. }
  54.  
  55. void SPFA(int s)
  56. {
  57. queue< int > q;
  58. while(!q.empty())
  59. q.pop();
  60. for(int i=; i<=n; i++)
  61. {
  62. h[i]=INF;
  63. vis[i]=;
  64. }
  65. h[s]=;
  66. vis[s]=;
  67. q.push(s);
  68. while(!q.empty())
  69. {
  70. int u=q.front();
  71. q.pop();
  72. vis[u]=;
  73. for(int i=rbe[u]; i!=-; i=re[i].ne)
  74. {
  75. int v=re[i].y;
  76. if(h[v]>h[u]+re[i].w)
  77. {
  78. h[v]=h[u]+re[i].w;
  79. if(!vis[v])
  80. {
  81. vis[v]=;
  82. q.push(v);
  83. }
  84. }
  85. }
  86. }
  87. }
  88.  
  89. int Astar(int s, int t, int k)
  90. {
  91. SPFA(t);
  92. if(h[s]==INF) return -;
  93. priority_queue< Point > q;
  94. while(!q.empty())
  95. q.pop();
  96. memset(vis,,sizeof(vis));
  97. memset(cnt,,sizeof(cnt));
  98. Point cur,nxt;
  99. cur.x=s;
  100. cur.g=;
  101. q.push(cur);
  102. while(!q.empty())
  103. {
  104. cur=q.top();
  105. q.pop();
  106. if((++cnt[cur.x])>k) continue;
  107. if(cnt[t]==k)
  108. return cur.g;
  109. for(int i=be[cur.x]; i!=-; i=e[i].ne)
  110. {
  111. nxt.x=e[i].y;
  112. nxt.g=cur.g+e[i].w;
  113. q.push(nxt);
  114. }
  115. }
  116. return -;
  117. }
  118.  
  119. void init()
  120. {
  121. all=;
  122. memset(be,-,sizeof(be));
  123. rall=;
  124. memset(rbe,-,sizeof(rbe));
  125. }
  126.  
  127. int main()
  128. {
  129. scanf("%d%d",&n,&m);
  130. init();
  131. for(int i=; i<m; i++)
  132. {
  133. scanf("%d%d%d",&x,&y,&w);
  134. add(x,y,w);
  135. radd(y,x,w);
  136. }
  137. scanf("%d%d%d",&s,&t,&k);
  138. if(s==t) k++;
  139. printf("%d\n",Astar(s,t,k));
  140. return ;
  141. }
  142.  
  143. /*
  144.  
  145. 2 4
  146. 1 2 1
  147. 1 2 2
  148. 1 2 3
  149. 2 1 5
  150. 1 2 5
  151.  
  152. */

POJ 2449 A*+SPFA的更多相关文章

  1. poj 2449 Remmarguts&#39; Date 【SPFA+Astar】【古典】

    称号:poj 2449 Remmarguts' Date 意甲冠军:给定一个图,乞讨k短路. 算法:SPFA求最短路 + AStar 以下引用大牛的分析: 首先,为了说话方便,列出一些术语: 在启示式 ...

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

    题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度. 解题思路:这道题是一道 ...

  3. POJ 2449:Remmarguts' Date(A* + SPFA)

    题目链接 题意 给出n个点m条有向边,源点s,汇点t,k.问s到t的第k短路的路径长度是多少,不存在输出-1. 思路 A*算法是启发式搜索,通过一个估价函数 f(p) = g(p) + h(p) ,其 ...

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

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

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

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

  6. poj 2449 k短路+A*算法

    http://poj.org/problem?id=2449 K短路的定义: 1.如果起点终点相同,那么0并不是最短路,而是要出去一圈回来之后才是最短路,那么第K短路也是一样. 2.每个顶点和每条边都 ...

  7. poj 2449 Remmarguts' Date(K短路,A*算法)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013081425/article/details/26729375 http://poj.org/ ...

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

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

  9. POJ 1860(spfa)

    http://poj.org/problem?id=1860 题意:汇率转换,与之前的2240有点类似,不同的是那个题它去换钱的时候,是不需要手续费的,这个题是需要手续费的,这是个很大的不同. 思路: ...

随机推荐

  1. linux xampp常见问题

    一.常见问题 1.安装xampp4linux后,只能本机(http://localhost)访问,局域网内其他机器无法访问 解答:在/opt/lampp/etc中修改httpd.conf,将Liste ...

  2. html+css学习笔记 5[表格、表单]

    表格 -- 默认样式重置 表格标签:     table 表格     thead 表格头     tbody 表格主体     tfoot 表格尾     tr 表格行     th 元素定义表头 ...

  3. 3044 矩形面积求并 - Wikioi

    题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...

  4. Netty4.x中文教程系列(三) ChannelHandler

    Netty4.x中文教程系列(四)  ChannelHandler 上一篇文章详细解释了Hello World示例的代码.里面涉及了一些Netty框架的基础. 这篇文章用以解释ChannelHandl ...

  5. tomcat7.0.47 修改tomcat窗口名称

    最近使用的是 apache - tomcat 集群,为了方便管理上想要修改tomcat命令窗口的名字来区分不同的tomcat,我在网上找了些资料,顺便总结一下,方便自己,方便他人 修改如下: 找到to ...

  6. CodeForces 173B Chamber of Secrets 二分图+最短路

    题目链接: http://codeforces.com/problemset/problem/173/B 题意: 给你一个n*m的地图,现在有一束激光从左上角往左边射出,每遇到‘#’,你可以选择光线往 ...

  7. 【BestCoder】【Round#29】

    T1 啊……a^b 与 c^d比较大小,我们可以两边取对数,转化成 log(a^b)=b*log(a) 和d*log(c) 这样就能直接算了……然后稍微搞一下精度什么的就A了=.= //BC #29 ...

  8. Enabled AWE

    sp_configure RECONFIGURE GO sp_configure RECONFIGURE GO sp_configure RECONFIGURE GO sp_configure REC ...

  9. nodeJS实战

    github代码托管地址: https://github.com/Iwillknow/microblog.git 根据<NodeJS开发指南>实例进行实战{{%并且希望一步步自己能够逐步将 ...

  10. IIS7.5 自定义Html/shtml/htm...后缀映射

    以添加html后缀的文件的 映射为例: 1.打开iis管理器,点击 2.点击打开处理程序映射 3.添加托管处理程序映射 4.请求路径 *.html 类型: System.Web.UI.PageHand ...