思路来源

https://blog.csdn.net/berrykanry/article/details/78345894(通俗易懂解释好评)

https://www.cnblogs.com/yyf0309/p/8438849.html(可惜看不懂可持久化可并堆)

题意

给定一个图,求第k短路,

相同长度不同路径的路被认为是不同的路,

若不存在输出-1。

题解

我才不会说我八数码题tleMLE了两天后补了一下A*算法又被安利来看这个破题

以终点为S进行dijkstra/spfa,

(具体实现可以建反向图)

然后得到了真实的评估函数h(n)的表,

这样我到了一个点,就知道已走路g(n)+前方最短路h(n)这条路的cost,

把它记为截止到该点的理想最短路。

显然,我们从起点dis[n]即最短路开始延展,

相当于bfs,由起点转向其一步可达点,

即由最短路,转向了后续状态可能换了一条边的最短路。

后者是实际意义上的次短,第三短等等等…

而没换边的路,被加进优先队列里之后,

由于其距离小,还应处在队顶的位置,只是其截止点往后推了一个,

若不存在环,最终所有点的截止点都会被推到终点,

而我们只需要这其中的前k个。

而由于优先队列按距离排序,

当其到达终点的时候,对终点计贡献,

说明这些路是截止到终点的,长度严格递增的路。

当计到第k时,即为起点可达终点的k短路。

这个题,引发了我深深的感慨。

在人生之路上,当你还在为自己的前途备一个list,

记录第一志愿,第二志愿,……,第k志愿并在线为其比较的时候,

早就有人已经洞若观火,知道自己第一志愿应该报哪,

并且,为了选择第k志愿,明明知道最短路在哪,

不惜比照着自己已经打好的dijkstra表,

开始往那些非最短路的地方瞎走???

瞎走一步,啊,这次走到了次短路,加到队列里,

瞎走两步…瞎走k步,啊终于找到了我要的k短路

高考空了50分 终于考上了理想第k大学 既视感

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <functional>
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
const int mod=1e9+7;
const int MOD=998244353;
const double eps=1e-7;
typedef long long ll;
#define vi vector<int>
#define si set<int>
#define pii pair<int,int>
#define pi acos(-1.0)
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define sci(x) scanf("%d",&(x))
#define scll(x) scanf("%lld",&(x))
#define sclf(x) scanf("%lf",&(x))
#define pri(x) printf("%d",(x))
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int n,m,s,t,k;
int head[1005],cnt,rehead[1005],qq[5005];
bool vis[1005];
int dis[1005];
struct edge{int to,nex,w;}e[100005],re[100005];
struct node
{int g;//当前已走 int f;//总 int id;//节点号 node(int a,int b,int c):g(a),f(b),id(c){}
};
bool operator>(node a,node b)
{if(a.f!=b.f)return a.f>b.f;return a.g>b.g;
}
priority_queue<pii,vector<pii>,greater<pii> >q;
priority_queue<node,vector<node>,greater<node> >p;
void init()
{ mem(head,-1);cnt=0;mem(rehead,-1);mem(vis,0);
}
void add(int u,int v,int w)
{e[cnt].to=v;//u->ve[cnt].w=w;e[cnt].nex=head[u];head[u]=cnt;re[cnt].to=u;//v->ure[cnt].w=w;re[cnt].nex=rehead[v];rehead[v]=cnt++;
}void spfa(int src)
{for(int i = 1; i <= n; i++) dis[i] = INF;mem(vis,0);int h = 0, t = 1;qq[0] = src;dis[src] = 0;while(h < t){int u = qq[h++];vis[u] = 0;for(int i = rehead[u] ; i != -1; i = re[i].nex){int v = re[i].to;int w = re[i].w;if(dis[v] > dis[u] + w){dis[v] = dis[u] + w;if(!vis[v]){qq[t++] = v;vis[v] = 1;}}}}
}
int astar(int s,int t)
{int num=0;if(s==t)k++;//注意这里,我们把s->s视作为0的最短路if(dis[s]==INF)return -1;while(!p.empty())p.pop();p.push(node(0,dis[s],s));//以t为视角的距离 while(!p.empty()){node tmp=p.top();p.pop();int g=tmp.g,f=tmp.f,u=tmp.id;if(u==t){num++; if(num==k)return g;}for(int j=head[u];~j;j=e[j].nex){int v=e[j].to,w=e[j].w;p.push(node(g+w,g+w+dis[v],v));}}return -1;
}
int main()
{    while(~scanf("%d%d",&n,&m)){init();rep(i,0,m-1){int u,v,w;scanf("%d%d%d",&u,&v,&w);add(u,v,w);}scanf("%d%d%d",&s,&t,&k);spfa(t);//对终点dijkstraprintf("%d\n",astar(s,t));}return 0;
}

poj2449 Remmarguts' Date(第k短路问题)(A*+spfa/dijkstra)相关推荐

  1. POJ 2449 Remmarguts' Date [第k短路]

    Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu Descripti ...

  2. POJ - 2449 Remmarguts' Date(第k短路:spfa+A*)

    题目链接:点击查看 题目大意:给出一个有向图,求第k短路 题目分析:偷学了一波A*,本来以为是多难的算法,其实就是bfs+优先队列的升级版,之前看的那些博客写的都太深奥了,以至于看了一半啥都没看懂然后 ...

  3. Poj2449 Remmarguts' Date 【A*搜索】K短路

    http://poj.org/problem?id=2449 A*搜索求K短路. #include <cstdio> #include <cstring> #include & ...

  4. A*算法的认识与求第K短路模板

    现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...

  5. A* 第k短路详解 (详尽)

    首先分享一个我学习的博客文章: Poj2449-A*初步+k短路 看着他的题解学会了k短路..%%% 然后我就大致说一说k短路的求法吧.. 首先我们来看看A*. A*,启发式搜索,是一种较为有效的搜索 ...

  6. POJ 2449 Remmarguts' Date(k短路模板)

    link:https://vjudge.net/problem/POJ-2449 前面输入与大多最短路题相同 最后一行输入s,t,k 求从s到t的第K短路 wiki link: https://en. ...

  7. POJ 2449 Remmarguts' Date(第K短路 + A* + 最短路)题解

    题意:找出第k短路,输出长度,没有输出-1 思路:这题可以用A*做.A*的原理是这样,我们用一个函数:f = g + h 来表示当前点的预期步数,f代表当前点的预期步数,g代表从起点走到当前的步数,h ...

  8. Remmarguts' Date(POJ2449+最短路+A*算法)

    题目链接:http://poj.org/problem?id=2449 题目: 题意:求有向图两点间的k短路. 思路:最短路+A*算法 代码实现如下: 1 #include <set> 2 ...

  9. poj2449(k短路算法)

    K 短路问题(A* 启发式广搜) 1.k 短路问题就是最短路问题的延申,要找出第 k 短的路径.用广搜进行路径查找,第一次找到的 就是最短路,第二次找到的是第 2 短 路⋯以此类推.所以我们只需要一直 ...

最新文章

  1. 华为托起小康股份、北汽蓝谷、长安汽车股价
  2. 小程序地图的使用笔记
  3. CEJ:西安理工赵亚乾组冠状病毒在水中传播特征、可能遏制策略与研究挑战
  4. position 再谈
  5. JS实现ul,li排序效果
  6. VS.Net 开发 MSN一样缓慢出来的提示信息的方法
  7. C++ Opengl 显示列表源码
  8. LINUX下配置bashrc文件/ PATH环境变量修改/别名/提示符
  9. Python模块整理(四):线程模块threading
  10. python的输出函数_Python
  11. 解决cv2.error: OpenCV(4.0.0)的方法
  12. 知乎:全球发售2600万股销售股份 每股发售价51.8港元
  13. php switch正则表达式,switch的用法以及正则表达式简单的用法
  14. 美国 AI 博士爆料:掌握这9个要点,赚钱不再艰难
  15. Linux——CentOS7安装gcc编译器详解
  16. 【C语言项目设计】趣味算术游戏设计
  17. 分布式系统统一登录的实现
  18. w7系统关闭打印服务器,w7打印后台处理程序服务总是自动停止如何解决【照片】...
  19. 天南星科系统发育及全基因组复制事件的研究取得新进展
  20. (阅读笔记)3DRA和CTA脑动脉瘤分割方法与评价

热门文章

  1. Windows本地认证和NTLM认证
  2. 邮箱-Mailbox
  3. C语言w10输入法打不出中文,Win10系统使用微软输入法打不出汉字的解决方法
  4. Quartus中如何找回画电路图时的工具栏(Block Editor)
  5. sql distinct多个字段
  6. 六步成就菜鸟seo走向高端之路
  7. paste deploy 解说和使用
  8. 科学家在类脑芯片上实现类似LSTM的功能,能效高1000倍
  9. FAT32和 NTFS功能上的差别
  10. 为什么说软件外包公司没前途