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)更小 ...
随机推荐
- 《自拍教程17》Python调用命令
他山之石 何为他山之石,就是借助外界工具,来实现自己想要的功能. 命令行界面软件, 即各种命令,我们也叫命令行工具, 此类工具也是测试人员或者开发人员常用的工具的一种. 测试人员可以借助这类工具,快速 ...
- 关于开源,Git,Github
在Github和Git上fork之简单指南 https://linux.cn/article-4292-1.html,中文翻译 https://www.dataschool.io/simple-gui ...
- java 自学简单框架(反射+注解)
1.先定义一个学生类 2.再定义一个teacher类(这个是为了练习多个注解,自己练习可以 不写这个) 3.再定义个一个学生老师类(这个是为了最终调用上面的那个学生类做准备) 4.下面开始真正的写框架 ...
- 杭电------2048神上帝以及老天爷(C语言写)
#include<stdio.h> ] = { -,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,- }; ] = { }; long long jiec ...
- 【查阅】Chrome快捷键
高频简要Chrome快捷键整理 记录一下Chrome常用快捷键方便查询熟悉,提高工作效率. 在我认为比较高频有用的快捷键,会加粗和标记. 在日常中熟练使用快捷键能帮助我们提高工作效率. 一 .F区单键 ...
- 用 Python 分析今年考研形势
还有5天,就到了考研初试的时间了. ! 尽管今年研招网内部,已经做了优化改善,还是抵挡不住考生们的报名热情(网站崩溃). 2017年考研人数增长至201万人, 2018年则达到238万人, 201 ...
- 学习css常用基本层级伪类属性选择器
常见的css选择器包含:常用选择器.基本选择器.层级选择器.伪类选择器.属性选择器,其中常用选择器分为:1.html选择符*{}//给页面上所有的标签设置模式:2.类选择符.hcls{}//给clas ...
- Cesium案例解析(五)——3DTilesPhotogrammetry摄影测量3DTiles数据
目录 1. 概述 2. 案例 3. 结果 1. 概述 3D Tiles是用于传输和渲染大规模3D地理空间数据的格式,例如摄影测量,3D建筑,BIM / CAD,实例化特征和点云等.与常规的模型文件格式 ...
- npm下载文件临时目录、实际存放目录路劲
npm 下载文件临时存放目录 路劲:C:\Users\xxxxxx\AppData\Roaming\npm\node_modules ( C:\Users\dihongwanyan\AppData\R ...
- mysql中EXPLAIN 的作用
(一)id列: (1).id 相同执行顺序由上到下 mysql> explain -> SELECT*FROM tb_order tb1 -> LEFT JOIN tb_produc ...