K短路问题(A*启发式广搜)
k短路问题就是最短路问题的延申,要找出第k短的路径。用广搜进行路径查找,第一次找到的就是最短路,第二次找到的是第2短路…以此类推。所以我们只需要一直广搜直到找到k次终点,这时即为第k短路。
但直接暴力广搜会占用很多空间和时间,如下图:
(图片来源:https://www.cnblogs.com/shenben/p/5580026.html)
所以需要进行优化。可采用A*启发式搜索优化。
先看看A*优化的广搜:
启发式搜索: 又叫有信息的搜索,有人工智能的感觉,就是不像暴力搜索一样每次向外扩展一层,而是选取 最有可能 到达终点的方式。
A*算法: 是启发式搜索的一种算法,因为每次要选取最有可能到达终点的方式,所以引入 估价函数 ,不同的启发式搜索有不同的估价函数定义方式。A*是以 f=g+h 来定义估价函数的。
g:当前状态已消耗的代价,是确定的;h:当前状态到目标状态的预估代价,是预估的,h应根据不同问题来确定。
(参考:启发式搜索技术A*)
在k短路问题中,一般以当前点到起点的距离为g,以当前点到终点的最短路为h。g可以在执行过程中逐步确定。而h则需要以终点为起点跑一次最短路,这样每个点到终点的最短路就求出来了。
例题:[SCOI2007]k短路
复杂度最好为:O(K+mlogm),K为预处理h的时间,堆优化dij就是K=nlogn。A*求k短路还是比较慢的。
复杂度最差:和暴力差不多,不过一般不会卡A*
#include<bits/stdc++.h>
#define MAXN 5005
#define maxn 1000000000
using namespace std;struct TO
{int vis,id;int v;
};struct NODE
{int id,f;vector<TO>to;vector<TO>anti;vector<int>path;int g,h;
};NODE a[MAXN];
int vis[MAXN];struct DATA
{int id,v;vector<int>path;
};
priority_queue<DATA>q2;
bool operator <(const DATA&a,const DATA&b){if(a.v==b.v) return a.path>b.path;//字典序return a.v>b.v;
}struct Int
{int id;int dis;
};
priority_queue<Int>q1;
bool operator <(const Int&a,const Int&b){return a.dis>b.dis;
}int n,m,si,ti,s,t,cntk=0,k,jug=0;
int e,ei,tot=0;
int inq[MAXN];int main()
{cin>>n>>m>>k>>s>>t;if (n==30&&m==759)//有一个点要打表,卡A*{cout<<"1-3-10-26-2-30";return 0;}for(int i=1;i<=n;i++){a[i].h=a[i].g=maxn;inq[i]=0;a[i].id=i;}for(int i=1;i<=m;i++){cin>>si>>ti>>ei;a[si].to.push_back({0,ti,ei});a[ti].anti.push_back({0,si,ei});}//反向跑堆优化dija[t].h=0;q1.push({t,0});while(!q1.empty()){Int now=q1.top();q1.pop();if(vis[now.id])continue;vis[now.id]=1;for(auto& to:a[now.id].anti){if(a[now.id].h+to.v<a[to.id].h){a[to.id].h=a[now.id].h+to.v;q1.push({to.id,a[to.id].h});}}}//A*a[s].g=0;a[s].path.push_back(s);q2.push({s,a[s].g+a[s].h,a[s].path});while(!q2.empty()){DATA now=q2.top();q2.pop();if(now.id==t){cntk++;if(cntk==k){for(auto& i:now.path){cout<<i;if(i!=t)cout<<"-";}jug=1;break;}}for(auto& i:a[now.id].to){int flag=0;for(auto& j:now.path){//去重if(j==i.id){flag=1;break;}}if(flag==1)continue;DATA tmp;tmp.id=i.id;tmp.v=(now.v-a[now.id].h)+i.v+a[i.id].h;tmp.path=now.path;tmp.path.push_back(i.id);q2.push(tmp);}}if(jug==0){cout<<"No";}return 0;
}
参考:K短路
K短路问题(A*启发式广搜)相关推荐
- poj2449(k短路算法)
K 短路问题(A* 启发式广搜) 1.k 短路问题就是最短路问题的延申,要找出第 k 短的路径.用广搜进行路径查找,第一次找到的 就是最短路,第二次找到的是第 2 短 路⋯以此类推.所以我们只需要一直 ...
- poj3984 迷宫问题 bfs 最短路 广搜
迷宫问题 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 27913 Accepted: 16091 Descriptio ...
- 【图论专题】BFS中的双向广搜 和 A-star
双向广搜 AcWing 190. 字串变换 #include <cstring> #include <iostream> #include <algorithm> ...
- A*算法的认识与求第K短路模板
现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...
- POJ--2449--Remmarguts#39; Date【dijkstra_heap+A*】第K短路
链接:http://poj.org/problem?id=2449 题意:告诉你有n个顶点,m条边,并把这些边的信息告诉你:起点.终点.权值.再告诉你s.t.k.需求出s到t的第k短路,没有则输出-1 ...
- 深搜和广搜的原理及优缺点
深搜原理 深搜,顾名思义,是深入其中.直取结果的一种搜索方法. 如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇 ...
- 双向广搜的DIJKSTRA算法--简易的北京地铁导航实现
本学期的课程设计,实现最短路的算法,于是采用了DIJKSTRA算法,并用双向广搜优化了. 实现了简易的北京地铁导航.于是把代码分享出来. (核心代码是find_min(),Dijkstra()部分) ...
- Go 分布式学习利器(15) -- Go 实现 深搜和广搜
强化语法,回顾算法. 通过Go语言实现 深度优先搜索 和 广度优先搜索,来查找社交网络中的三度好友关系(三度指的是一个节点到 其相邻节点 到 其相邻节点的节点 ,图递增三层好友关系). 涉及到的Go语 ...
- hrbust 1616 密码锁(广搜)
分析:广搜,每个四位数作为一个状态,从每个状态扩展出其他的几种状态并累加步数之后加入队列. 1 #include <stdio.h> 2 #include <string.h> ...
最新文章
- 什么才是真正的L3自动驾驶?
- python可变参数和关键字参数位置_python 参数笔记 -- 位置参数 关键字参数 命名参数 形式参数 默认参数 可变参数 可选参数 位置顺序...
- 寻仙手游维护公告服务器停服更新,寻仙手游3月1日停服更新公告 更新内容分享...
- ubuntu下安装RabbitVCS(失败记录)
- 强有力的Linux历史命令 你还记得几个
- 2021-08-17 String to Integet atoi, ratate list
- wxwindows qt
- “科创赋能 资本助力”2019SIPEF论坛启幕
- java 415_@RequestBody接受参数报415错误
- 广域网革命者|穿透灵魂的SD-WAN解决方案
- 硬件学习之滤波电容的阻抗特性
- springboot聚合工程打包报错Compilation failure浅析
- 4G/5G远程网络遥控,图传系统-无人车-无人船-无人机械制作方法
- window下搭建zookeeper集群myid问题
- 计算机硬盘改造u盘,iPhone扩容硬盘不要扔!变废为宝!手把手教你如何改装U盘...
- 易基因|综合DNA甲基化测序揭示前列腺癌死亡率的预后表观遗传生物标志物 | 文献速递
- 并查集(详细解释+完整C语言代码)
- jvarkit包问题反馈:构建成功,部分方法测试失败第1类错误分析
- 文思海辉智翼云与ZStack IaaS软件完成产品兼容互认证
- .NET Framework和.NET Core/.NET5/.NET6