注:\(A*\) 求解K短路效率极其低下,时间复杂度\(O(nklog\ n)\),空间视题目而定,因为本质是爆搜,可求解数据范围较小的题目。

我们使用\(A*\)求解k短路:

首先需要预处理出估价函数。对于原图建立反向图,然后跑终点的单源最短路。用终点到这个点的距离作为\(A*\)的估价函数,可以完全保证搜索准确性。

然后我们跑\(A*\)。每次从优先队列里取出当前步数与估价函数之和最小的点并扩展其所有边。对于每个状态我们需要开一个标记数组(或者路径数组也可以),防止重复经过同一个点。

此时我们每次从优先队列取出的都是当前最短路径,当一个点第k次被取出时,这条路径就是k短路。

提供一道毒瘤例题P4467 SCOI2007k短路

这题似乎是公认的卡A*(只卡了一个点,所以被用作\(A*\)求k短路的模板题)

特判用代码:

if(n==30&&m==759){
printf("1-3-10-26-2-30");
return 0;
}

这个题我们需要求出具体的路径,并且路径需要按照字典序排序后选择。

这题毒瘤就毒瘤在卡空间,所以我们就只开一个存储路径的vector,然后重载运算符即可(vector好像自带一个比较 是比较字典序)

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define file(a) freopen(#a".in","r",stdin),freopen(#a".out","w",stdout)
#define LL long long
#define INF 0x3f3f3f3f
#define N 60
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||'9'<ch){if(ch=='-')f=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){s=s*10+(ch^48);ch=getchar();}
return s*f;
}
int n,m,k;
namespace f{
int tot=-1;
int head[N],to[N*N],nxt[N*N],val[N*N];
void join(int u,int v,int w){
nxt[++tot]=head[u];
head[u]=tot;
to[tot]=v;
val[tot]=w;
}
}
int tot=-1;
int head[N],to[N*N],nxt[N*N],val[N*N];
void join(int u,int v,int w){
nxt[++tot]=head[u];
head[u]=tot;
to[tot]=v;
val[tot]=w;
}
int H[N],cnt[N];
bool inq[N];
queue<int>Q;
void spfa(int s){
for(int i=1;i<=n;++i){
H[i]=INF;
}
H[s]=0;inq[s]=1;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();inq[u]=0;
for(int i=f::head[u];~i;i=f::nxt[i]){
if(H[f::to[i]]>H[u]+f::val[i]){
H[f::to[i]]=H[u]+f::val[i];
if(!inq[f::to[i]]){
inq[f::to[i]]=1;
Q.push(f::to[i]);
}
}
}
}
}
struct node{
int p,t;
vector<int>ans;
friend bool operator<(node x,node y){
int tmp1=x.t+H[x.p],tmp2=y.t+H[y.p];
if(tmp1==tmp2) return x.ans>y.ans;
return tmp1>tmp2;
}
};
priority_queue<node>q;
void Astar(int s,int t){ node tmp;
tmp.p=s;tmp.t=0;tmp.ans.push_back(s);
q.push(tmp);
while(!q.empty()){
node x=q.top();q.pop();
int u=x.p;++cnt[u];
if(u==t&&cnt[u]==k){
for(int i=0;i<x.ans.size();++i){
if(i!=0) putchar('-');
printf("%d",x.ans[i]);
}
return;
}
for(int i=head[u];~i;i=nxt[i]){
bool flag=0;
for(int j=0;j<x.ans.size();++j){
if(x.ans[j]==to[i]){
flag=1;
break;
}
}
if(flag) continue;
node tmp2;
tmp2=x;tmp2.ans.push_back(to[i]);
tmp2.p=to[i];tmp2.t+=val[i];
q.push(tmp2);
}
}
printf("No");
}
int s,t;
int main(){
n=read();m=read();k=read();s=read();t=read();
if(n==30&&m==759){
printf("1-3-10-26-2-30");
return 0;
}
memset(head,-1,sizeof(head));memset(f::head,-1,sizeof(f::head));
for(int i=1;i<=m;++i){
int u=read(),v=read(),w=read();
join(u,v,w);f::join(v,u,w);
}
spfa(t);
Astar(s,t);
return 0;
}

A* K短路的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 第k短路

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

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

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

  8. K短路

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

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

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

  10. bzoj 1975 [Sdoi2010]魔法猪学院(k短路)

    题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...

随机推荐

  1. python大佬养成计划----基于flask_sqlalchemy的网页显示数据库信息

    网页显示数据库信息 使用我们刚学习的flask_sqlalchemy,在网页中显示数据库表中的数据.在开始运行程序前,确保数据库中执行过创建表和创建用户的操作,详见链接描述. # 模板文件templa ...

  2. 获取bootstrap模态框点击的对应项(e.relatedTarget.dataset)

    //获取绑定的自定义属性值<ul> <li data-toggle="modal" data-index="电表1111" data-targ ...

  3. 最小栈问题:题目描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

    MinStack minStack = new MinStack();minStack.push(-2);minStack.push(0);minStack.push(-3);minStack.get ...

  4. uni-app中实现图片左滑的效果

    template: 1 <view class="my-reg"> 2 <view class="my-regs"> 3 <ima ...

  5. JavaScript 字符串(String)对象的方法

    anchor() 描述:用于创建 HTML 锚 原型:stringObject.anchor(anchorname) 用法: <script> var txt="Hello wo ...

  6. Nestjs模块机制的概念和实现原理

    1 前言 Nest 提供了模块机制,通过在模块装饰器中定义提供者.导入.导出和提供者构造函数便完成了依赖注入,通过模块树组织整个应用程序的开发.按照框架本身的约定直接撸一个应用程序,是完全没有问题的. ...

  7. Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏

    本文绘制的地图效果图如下: 一.Echarts 使用五部曲 1.下载并引入 echarts Echarts 已更新到了 5.0 版本,安装完记得检查下自己的版本是否是 5.0 . npm instal ...

  8. k8s pod 在迁移zookeeper时出现的问题

    一次迁移中出现的问题,因为要搬迁机房,集群中的节点服务器分布在两个机房,通过专线打通了,现在需要整体都迁移到其中一个机房,所以pod要进行迁移,机器资源也比较紧张,在迁移中zookeeper迁移出现问 ...

  9. springboot中bean的重定义

    需求描述: 项目中应用其他项目的jar包,然后有些controller中的方法有缺陷需要修改. 1.配置添加 spring.main.allow-bean-definition-overriding= ...

  10. *CTF babyarm内核题目分析

    本文从漏洞分析.ARM64架构漏洞利用方式来讨论如何构造提权PoC达到读取root权限的文件.此题是一个ARM64架构的Linux 5.17.2 版本内核提权题目,目的是读取root用户的flag文件 ...