A*模板(求K短路)(POJ2449)
A*是bfs的优化,IDA*是dfs的优化
A*算法: 为启发式算法中很重要的一种,被广泛应用在最优路径求解和一些策略设计的问题中。而A*算法最为核心的部分,就在于它的一个估值函数的设计上:
f(n)=g(n)+h(n) 其中f(n)是每个可能试探点的估值,它有两部分组成:一部分为g(n),它表示从起始搜索点到当前点的代价(通常用某结点在搜索树中的深度来表示)。另一部分,即h(n),它表示启发式搜索中最为重要的一部分,即当前结点到目标结点的估值,h(n)设计的好坏,直接影响着具有此种启发式函数的启发式算法的是否能称为A*算法。
题目(代码和原题稍微不同):
链接:POJ2449
第一行为n个点,m条边,求第k短路。
接下来m行,每行3个数,代表起点、终点、边权。
输出第k短路的路径长度。
解法:
K短路的定义:假设从1出发,有M条长度不同的路径可以到达点N,则K短路就是这M条路径中第K小的路径长度。 以上所述,设f[n]为最终所求,则f(n)=g(n)+h(n);h(n)就是我们所说的‘启发式函数’,表示为重点t到其余一点p的路径长度,g(n)表示g当前从s到p所走的路径的长度。
即:估价函数=当前值+当前位置到终点的距离Solution:
(1)将有向图的所有边反向,以原终点t为源点,求解t到所有点的最短距离;
(2)新建一个优先队列,将源点s加入到队列中;
(3)从优先级队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数;
如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束;
否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列;
代码如下:
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int inf = 999999999;
const int maxn = 500000 + 5;
int n, m, k, s, t;
struct edge {
int v, w;
};
vector<vector<edge>>a, b;
vector<int>dis(maxn, inf);
vector<bool>flag(maxn, false);
//f(n)=g(n)+h(n)
//估价函数=当前值+当前位置到终点的距离
struct node {
int id;///当前节点编号
int f;//f表示经过当前节点的最短路
int g;//g表示S->当前节点的最短路
node(int id = 0, int f = 0, int g = 0) :id(id), f(f), g(g) {}
bool operator <(const node &a)const {//估价函数值大或者距初始点最长的结点优先级高
if (f == a.f) return g>a.g;
return f>a.f;
}
};
void add_edge(int u, int v, int w) {
edge tmp;
tmp.v = u; tmp.w = w; a[v].push_back(tmp);
tmp.v = v; tmp.w = w; b[u].push_back(tmp);
}
void spfa(int s) {
queue<int>q;
q.push(s);
dis[s] = 0; flag[s] = true;
while (!q.empty()) {
int u = q.front(); q.pop(); flag[u] = false;
for (int i = 0; i < a[u].size(); i++) {//扫描所有邻接点
if (dis[a[u][i].v] > dis[u] + a[u][i].w) {
dis[a[u][i].v] = dis[u] + a[u][i].w;
if (!flag[a[u][i].v]) {
q.push(a[u][i].v);
flag[a[u][i].v] = true;
}
}
}
}
}
void Astar(int s, int t) {
if (s == t)k++;//没有这句会T
if (dis[s] == inf){ printf("-1\n"); return; }//没有这句会T
priority_queue<node>q;
q.push(node(s, 0, 0));
int cnt = 0;
while (!q.empty()) {
node h = q.top(); q.pop();
if (h.id == t) {
if (++cnt == k) {
printf("%d", h.f);//返回第k短路
return;
}
}
for (int i = 0; i < b[h.id].size(); i++) {
q.push(node(b[h.id][i].v, h.g + b[h.id][i].w + dis[b[h.id][i].v], h.g + b[h.id][i].w));
}
}
printf("-1\n"); return;
}
int main() {
a.resize(maxn);
b.resize(maxn);
scanf("%d%d%d", &n, &m, &k);
scanf("%d%d", &s, &t);
int u, v, w;
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &u, &v, &w);
add_edge(u, v, w);
}
spfa(t);
Astar(s, t);
return 0;
}
A*模板(求K短路)(POJ2449)的更多相关文章
- P2483 【模板】k短路([SDOI2010]魔法猪学院)
题目背景 感谢@kczno1 @X_o_r 提供hack数据 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界 ...
- bellman-ford算法求K短路O(n*m),以及判负环O(n*m)
#include<iostream> #include<algorithm> #include<cstring> using namespace std; cons ...
- Luogu P2483 【模板】k短路([SDOI2010]魔法猪学院)
说实话,看到这道题的洛谷评级我傻了(传说中的最高难度) 然后看完题目才确定这真的是一道k短路的裸题. 也就敲了个A*吧,15分钟竟然没有调试一遍过. 欧洲玄学. 看题目,主要是找几条从1走到n的路加起 ...
- BZOJ 1975 魔法猪学院(A*求K短路)
显然每次贪心的走最少消耗的路径即可.那么也就是找出最短路,次短路,,,K短路之后消耗E的能量的最多的路径条数. 也就是裸的A*算法. #include <bits/stdc++.h> us ...
- 【洛谷 P2483】 【模板】k短路([SDOI2010]魔法猪学院)(A*)
题目链接 优先队列bfs第一次出队就是最短路,那么显然第k次出队就是k短路 ?????????????????????????????? 书上写的 但是直接优先队列bfs会T,所以用A*优化就行,估价 ...
- A*算法求K短路模板 POJ 2449
#include<cstdio> #include<queue> #include<cstring> using namespace std; const int ...
- 【模板】K短路 A-star
引理:当一个状态对应的节点第K次从堆中取出时,该状态对应的当前代价是从起点到该点的第K优解. 代码如下 /* POJ2449 */ #include <cstdio> #include & ...
- luogu2483 【模板】k短路([SDOI2010]魔法猪学院)
模板题 #include <iostream> #include <cstring> #include <cstdio> #include <queue> ...
- 第K短路模板【POJ2449 / 洛谷2483 / BZOJ1975 / HDU6181】
1.到底如何求k短路的? 我们考虑,要求k短路,要先求出最短路/次短路/第三短路……/第(k-1)短路,然后访问到第k短路. 接下来的方法就是如此操作的. 2.f(x)的意义? 我们得到的f(x)更小 ...
随机推荐
- 《自拍教程24》在Windows上配置环境变量
我们说的环境变量,一般是指的是Path环境变量. 第一步:点击"我的电脑",右键,"属性" 第二步:点击"高级系统设置",弹出的窗口选&qu ...
- Flutter Widgets 之 FutureBuilder
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 展示异步任务状态 当有一个Future(异步)任务需要展示 ...
- Nodejs中,path.join()和path.resolve()的区别
在说path.join()和path.resolve()的区别之前,我先说下文件路径/和./和../之间的区别 /代表的是根目录: ./代表的是当前目录: ../代表的是父级目录. 然后再来说下pat ...
- IT运维大会精华回顾 等保2.0时代掌控万物互联
10月24日,由<网络安全和信息化>杂志社.IT运维网联合主办的“2019(第十届)IT运维大会”在北京新世纪日航酒店成功举行. 随着大数据.云计算.物联网.互联网+等快速发展,IT系统架 ...
- Java 添加超链接到Excel文档
超链接即内容链接,通过给特定对象设置超链接,可实现载体与特定网页.文件.邮件.网络等的链接,点击链接载体可打开链接目标,在文档处理中是一种比较常用的功能.本文将介绍通过Java程序给Excel文档添加 ...
- 9种分布式ID生成之 美团(Leaf)实战
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 更多优选 一口气说出 9种 分布式ID生成方式,面试官有点懵了 ...
- transition 过渡的兼容性处理
transition兼容性: 封装一个js来验证浏览器是否兼容transition,以及选择兼容的写法 以下是transition.js (function(){ //判断transition属性是否 ...
- Windows、Linux之间传输文件的几种方式
常见的文件传输协议有ftp.sftp,sftp就是在ftp的基础上对传输的数据进行了加密. ftp速度快,sftp速度略慢但安全性高. ftp默认使用21端口,sftp默认使用22端口. 我使用的是C ...
- 从零开始一个个人博客 by asp.net core and angular(二)
上一篇帖子讲了用了哪些技术,这个帖子就先介绍介绍api项目吧,项目就是一个普通的webapi项目,账户系统用的identity ,什么是identity呢? 其实就是官方封装好的一系列的可以用来操作数 ...
- 初学Python,需要装什么软件?
学习Python需要安装什么软件呢?也许你是一位编程小白,还不知道如何如何安装Python软件和开发环境.那么今天我们就来学一下关于Python软件.开发环境的相关知识,希望对你有用. 学Python ...