注:\(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. 使用自定义的鼠标图标 --- cursor url

    前段时间在项目中遇到过 自定义鼠标图标 这一需求.由于一般我们用的鼠标样式大都是固定的几种,而 自定义鼠标图标 不是很常用到,所以对这一小知识点进行总结,以防忘记. 自定义鼠标图标 自定义鼠标图标 即 ...

  2. java中抽象类和抽象方法到底有什么用呢?

    抽象类和抽象方法有什么用呢?马克-to-win:当初sun公司为什么要设计抽象类和抽象方法呢?当你在做车的系统设计时,当你设计车这个通用类时,假如你确认别人实例化车这个通用类没有意义时(不知道是bik ...

  3. 用 JS(JavaScript )实现增删改查

    JS小例题 学习内容: 需求 总结: 学习内容: 需求 用 JavaScript 实现简单增删改查 实现代码 <!DOCTYPE html PUBLIC "-//W3C//DTD HT ...

  4. spring-Bean依赖注入-》普通数据类型

    1.创建UserDao接口以及UserDaoImpl实现类(接口代码省略) public class UserDaoImpl implements UserDao { private String u ...

  5. python中其他数据类型内置方法

    补充字符串数据类型内置方法 1.移除字符串首尾的指定字符可以选择方向1: s1 = '$$$jason$$$' print(s1.strip('$')) # jason print(s1.lstrip ...

  6. allure用法(一)-配置信息及基本用法

    allure是一个轻量级的,灵活的,支持多语言的测试报告工具 优点: 可以为dev/qa 提供 详尽的测试报告.测试步骤.日志 可以为管理层提供更好的统计报告 Java语言开发的 可以集成到jenki ...

  7. 五、JDK的安装与配置

    一.JDK下载与安装 1.1.下载JDK安装包 博主在这里给大家准备了一个64位操作系统的jdk1.8以便大家下载(使用的是迅雷) 点击此处下载 提取码:dfbt 如果其他小伙伴的电脑版本不一样,博主 ...

  8. javascript中的Ajax基础(一)

    一.手写一个ajax 1 const xhr = new xmlHttpRequest() 2 3 xhr.open(请求方式:post get, 请求地址, 同步或者异步) 4 5 xhr.onre ...

  9. 如何基于ZEGO SDK 实现通话质量监测

    如何基于ZEGO SDK 实现通话质量监测 1 功能简介 在进行视频通话过程中,用户有时候会出现网络不好的情况,比如在进行多人视频通话或者多人唱歌时,我们需要实时显示用户的网络质量. 示例源码 请参考 ...

  10. echarts踩坑总结

    1,有关echarts引用的相关报错直接写这句  import * as echarts from 'echarts' 2,折线图 chartsObj = { tooltip: { trigger: ...