A* K短路
注:\(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短路的更多相关文章
- POJ 2449 Remmarguts' Date --K短路
题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...
- POJ 2449Remmarguts' Date K短路模板 SPFA+A*
K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...
- BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...
- 【POJ】2449 Remmarguts' Date(k短路)
http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...
- poj 2449 Remmarguts' Date K短路+A*
题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...
- 第k短路
poj 2449 模板题 A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...
- poj 2449(A*求第K短路)
题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...
- K短路
K短路 用dijsktra+A*启发式搜索当点v第K次出堆的时候,这时候求得的路径是k短路.A*算法有一个启发式函数f(p)=g(p)+h(p), 即评估函数=当前值+当前位置到终点的最短距离g(p) ...
- poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)
http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
- bzoj 1975 [Sdoi2010]魔法猪学院(k短路)
题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...
随机推荐
- 前端调试利器 - Charles
Docs 开发之 Charles 配置指南 1.下载与安装 charles-proxy-4.1.4 .dmg56.12 MB已存到云盘下载 2.激活 使用公司正版license 激活 安装证书 点击证 ...
- CCF201903-2二十四点
思路描述:最开始的思路是拿一个栈来存储数据和符号,在动手实践的过程中发现行不通,单个数字的char和int转换可以,但是加起来的数据两位数字就很难处理了. 然后就去看了看别人的思路,给了我一个很好的启 ...
- 浅谈js本地图片预览
最近在工作中遇到一个问题,就是实现一个反馈页面,这个反馈页面的元素有反馈主题.反馈类型.反馈内容.反馈人联系电话以及反馈图片.前端将这些反馈的元素POST给后台提供的接口:实现这个工作的步骤就是:页面 ...
- vue点击按钮复制文本框内容
1.npm进行安装 npm install clipboard --save 2.在需要使用的组件中import 引用方法:import Clipboard from 'clipboard'; 3.添 ...
- 去掉有定位的left值
left: initial; 一开始就是初始(默认值)的意思,就可以解决定位的left啦
- Python入门-面向对象三大特性-多态
Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚"鸭子类型".
- Struts2-值栈的定义
1.值栈的概念:在Struts2里面提供本身的一种储存机制,类似于域对象,可以存值和取值(可以类比Servlet中的域对象->request,session,application) 2.具体操 ...
- 我们如何上传docker到habor上呢
Docker 打包上传habor认证 首先在 Maven 的配置文件 setting.xml 中增加相关 server 配置,主要配置 Docker registry(远程仓库)用户认证信息. < ...
- java并发问题总结
1.java中产生并发问题的主要原因有哪三个? 原子性.可见性和有序性 2.什么是java内存模型? java虚拟机规范中用来屏蔽掉各种硬件和操作系统内存访问差异,java内存模型的主要目标是定义程序 ...
- JavaWeb学习day2-web入门&随笔
Tomcat详解: 1默认端口号: Tomcat:8080 Mysql:3306 http:80 https:443 2默认主机名:localhost 地址:127.0.0.1 3网站应用默认存放位置 ...