K最短路问题(单源点最短路径+A*算法)

摘要:
inq[edge[k].to]){inq[edge[k].to]++;Q1.push;}}k=edge[k].next;}}returntrue;}intA_star{node2e,ne;intcnt=0;priority_queueQ;if//当s==t时,距离为0的路不能算在这k短路中,所以需要求k+1短路;k++;ifreturn-1;e.to=s;e.g=0;e.f=e.g+dist[e.to];Q.push;while(!Q.empty()){e=Q.top();Q.pop();if//找到一条最短路径{cnt++;}if//找到k短路{returne.g;}for(inti=head[e.to];i!=-1;i=edge[i].next){ne.to=edge[i].to;ne.g=e.g+edge[i].w;ne.f=ne.g+dist[ne.to];Q.push;}}return-1;}intmain(){intn,m;//freopen;while{memset;memset;idx1=idx2=0;intu,v,w;for{scanf;Addedge1;Addedge2;}ints,t,k;scanf;SPFA;//以原终点t为源点,求反向图中t到所有点的最短距离;intres=A_star;printf;}return0;}
[cpp]view plaincopyprint?
    1. /*
    2. *算法引入:
    3. *在单源点最短路径问题中,实际运用时还需知道最短路径外,次短路或者第三短路;
    4. *即要知道多条最短路,并排出其长度增加的顺序,即为K最短路问题;
    5. *
    6. *算法思想:
    7. *单源点最短路径+高级搜索A*;
    8. *A*算法结合了启发式方法和形式化方法;
    9. *启发式方法通过充分利用图给出的信息来动态地做出决定而使搜索次数大大降低;
    10. *形式化方法不利用图给出的信息,而仅通过数学的形式分析;
    11. *
    12. *算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向;
    13. *当这条路径失败时,它会尝试其他路径;
    14. *对于A*,估价函数=当前值+当前位置到终点的距离,即f(p)=g(p)+h(p),每次扩展估价函数值最小的一个;
    15. *
    16. *对于K短路算法来说,g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度;
    17. *f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远;
    18. *
    19. *为了加速计算,h(p)需要在A*搜索之前进行预处理,只要将原图的所有边反向,再从终点t做一次单源点最短路径就能得到每个点的h(p)了;
    20. *
    21. *算法步骤:
    22. *(1),将有向图的所有边反向,以原终点t为源点,求解t到所有点的最短距离;
    23. *(2),新建一个优先队列,将源点s加入到队列中;
    24. *(3),从优先级队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数;
    25. *如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束;
    26. *否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列;
    27. *
    28. *算法测试:
    29. *PKU2449(Remmarguts'Date)
    30. *
    31. *题目大意:
    32. *求从s到t的第k短路的长度;
    33. */
    34. #include<iostream>
    35. #include<cstring>
    36. #include<cstdlib>
    37. #include<queue>
    38. #include<cstdio>
    39. #include<climits>
    40. #include<algorithm>
    41. usingnamespacestd;
    42. constintINF=0xffffff;
    43. constintN=1010;
    44. constintM=100010;
    45. structnode1
    46. {
    47. intto;
    48. intw;
    49. intnext;
    50. };
    51. node1edge1[M],edge2[M];
    52. inthead1[M],head2[M];
    53. intidx1,idx2;
    54. intdist[N];
    55. structnode2
    56. {
    57. intto;
    58. //g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度;
    59. intg,f;//f=g+h,f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远;
    60. booloperator<(constnode2&r)const
    61. {
    62. if(r.f==f)
    63. returnr.g<g;
    64. returnr.f<f;
    65. }
    66. };
    67. voidAddedge1(intu,intv,intw)
    68. {
    69. edge1[idx1].w=w;
    70. edge1[idx1].to=v;
    71. edge1[idx1].next=head1[u];
    72. head1[u]=idx1++;
    73. }
    74. voidAddedge2(intu,intv,intw)
    75. {
    76. edge2[idx2].w=w;
    77. edge2[idx2].to=v;
    78. edge2[idx2].next=head2[u];
    79. head2[u]=idx2++;
    80. }
    81. boolSPFA(ints,intn,inthead[],node1edge[],intdist[])
    82. {
    83. queue<int>Q1;
    84. intinq[N];
    85. for(inti=0;i<=n;i++)
    86. {
    87. dist[i]=INF;
    88. inq[i]=0;
    89. }
    90. dist[s]=0;
    91. Q1.push(s);
    92. inq[s]++;
    93. while(!Q1.empty())
    94. {
    95. intq=Q1.front();
    96. Q1.pop();
    97. inq[q]--;
    98. if(inq[q]>n)//负权环
    99. returnfalse;
    100. intk=head[q];
    101. while(k>=0)
    102. {
    103. if(dist[edge[k].to]>dist[q]+edge[k].w)
    104. {
    105. dist[edge[k].to]=edge[k].w+dist[q];
    106. if(!inq[edge[k].to])
    107. {
    108. inq[edge[k].to]++;
    109. Q1.push(edge[k].to);
    110. }
    111. }
    112. k=edge[k].next;
    113. }
    114. }
    115. returntrue;
    116. }
    117. intA_star(ints,intt,intn,intk,inthead[],node1edge[],intdist[])
    118. {
    119. node2e,ne;
    120. intcnt=0;
    121. priority_queue<node2>Q;
    122. if(s==t)//当s==t时,距离为0的路不能算在这k短路中,所以需要求k+1短路;
    123. k++;
    124. if(dist[s]==INF)
    125. return-1;
    126. e.to=s;
    127. e.g=0;
    128. e.f=e.g+dist[e.to];
    129. Q.push(e);
    130. while(!Q.empty())
    131. {
    132. e=Q.top();
    133. Q.pop();
    134. if(e.to==t)//找到一条最短路径
    135. {
    136. cnt++;
    137. }
    138. if(cnt==k)//找到k短路
    139. {
    140. returne.g;
    141. }
    142. for(inti=head[e.to];i!=-1;i=edge[i].next)
    143. {
    144. ne.to=edge[i].to;
    145. ne.g=e.g+edge[i].w;
    146. ne.f=ne.g+dist[ne.to];
    147. Q.push(ne);
    148. }
    149. }
    150. return-1;
    151. }
    152. intmain()
    153. {
    154. intn,m;
    155. //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);
    156. while(~scanf("%d%d",&n,&m))
    157. {
    158. memset(head1,-1,sizeof(head1));
    159. memset(head2,-1,sizeof(head2));
    160. idx1=idx2=0;
    161. intu,v,w;
    162. for(inti=0;i<m;i++)
    163. {
    164. scanf("%d%d%d",&u,&v,&w);
    165. Addedge1(u,v,w);
    166. Addedge2(v,u,w);
    167. }
    168. ints,t,k;
    169. scanf("%d%d%d",&s,&t,&k);
    170. SPFA(t,n,head2,edge2,dist);//以原终点t为源点,求反向图中t到所有点的最短距离;
    171. intres=A_star(s,t,n,k,head1,edge1,dist);
    172. printf("%d\n",res);
    173. }
    174. return0;
    175. }

免责声明:文章转载自《K最短路问题(单源点最短路径+A*算法)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux mailbox模型【转】Flutter实战视频-移动电商-43.详细页_补充首页跳转到详细页下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

中文分词工具探析(一):ICTCLAS (NLPIR)

【开源中文分词工具探析】系列: 开源中文分词工具探析(一):ICTCLAS (NLPIR) 开源中文分词工具探析(二):Jieba 开源中文分词工具探析(三):Ansj 开源中文分词工具探析(四):THULAC 开源中文分词工具探析(五):FNLP 开源中文分词工具探析(六):Stanford CoreNLP 开源中文分词工具探析(七):LTP 1...

PostGIS拓扑:pgRouting最短路径分析

前提:在PostgreSQL中建立PostGIS数据库,安装pgRouting插件,导入现有的线表shp数据(示例使用的是管线pipesectionmain,其他的线表数据均可)。 1、pgRouting在edge表中添加字段 线表中必须有id,source,target,cost,the_geom 5个字段,其中现有空间数据表中的gid可作为id,sha...

利用分支限界法求解单源最短路(Dijkstra)问题

分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法。 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分支,不断重复这一过程,直到找到答案或者判定无解。 分支界限法常常用到优先队列来选择最佳扩展节点,有时也会用到普通队列,以先进先出为原则来进行筛选。 单源最短路...

ArcGIS 网络分析[1.2] 利用1.1的线shp创建网络数据集/并简单试验最佳路径

上篇已经创建好了线数据(shp文件格式)链接:点我 这篇将基于此shp线数据创建网络数据集。 在此说明:shp数据的网络数据集仅支持单一线数据,也就是说基于shp文件的网络数据集,只能有一个shp线文件参与。 如何解决这个弊端呢?见下篇,利用地理数据库即可。 本篇目录: 1. 创建网络数据集 2. 给网络数据集命名 3. 转弯 4. 连通性 5. 高程...

JS实现最短路径之迪杰斯特拉(Dijkstra)算法

最短路径:   对于网图来说,最短路径是指两个顶点之间经过的边上权值和最少的路径,我们称第一个顶点是源点,最后一个顶点是终点 迪杰斯特拉 ( Dijkstra) 算法是并不是一下子就求出 了 Vo 到V8 的最短路径,而是一步步求出它们之间顶点的最短路径,过程中都是基于已经求出的最短路径的基础上,求得更远顶点的最短路径,最终得到你要的结果   JS代码:...

1030 Travel Plan (30 分)(最短路径 and dfs)

#include<bits/stdc++.h> using namespace std; const int N=510; const int inf=0x3f3f3f3f; int mp[N][N]; bool vis[N]; int dis[N]; int n,m,s,D; int cost[N][N]; vector<int&g...