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)更小 ...
随机推荐
- hadoop简介和环境
Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个 ...
- 1336 - Sigma Functio
1336 - Sigma Function Sigma function is an interesting function in Number Theory. It is denoted by t ...
- centos系统重装python或yum 报There was a problem importing one of the Python modules required to run yum. The error leading to this problem was:错误
sudo vim /usr/bin/yum #修个python所在的路径,例如 #/usr/local/bin/python2.6 或 /usr/local/bin/python2.7要原本你的系统原 ...
- jsessionid與cookie關係的理解
本地測試地址為http://localhost/TEST/login.jsf 當瀏覽器打開cookie時,瀏覽器第一次與服務器建立連接,會創建一個session,並生成一個id即jsessionid, ...
- 0226 rest接口设计
背景 为了更方便的书写和阐述问题,文章中按照第一人称的角度书写.作为一个以java为主要开发语言的工程师,我所描述的都是java相关的编码和设计. 工程师的静态输出就是代码和文 ...
- Go1.14发布了,快来围观新的特性啦
如期而至,Go1.14发布了,和往常一样,该版本保留了Go 1兼容性的承若,这个版本的大部分更新在工具链 .运行时库的性能提升方面,总的来说,还是在已有的基础上不断优化提成,大家期待的泛型还没有到来, ...
- Myeclipse maven项目转web项目
右键点击项目,选择project facets,或者在properties选择,点“Convert to faceted from...” 勾选java和Dynamic Web Module 选项 接 ...
- 2、CentOS7密码重置
一.重启系统,在开机过程中,快速按下键盘上的方向键↑和↓.目的是告知引导程序,我们需要在引导页面选择不同的操作,以便让引导程序暂停. 以下是暂停后的界面,可以查看下方的英文可知↑和↓的作用. 二. ...
- 回炉重造之重读Windows核心编程-001-错误处理
Windows处理错误靠的是API的返回值,类型不止一种种: VOID,函数不可能失败,Windows API的返回值很少是这个情况. BOOL,如果函数失败,则返回值是0,否则返回是非零值.不要测试 ...
- ADO.NET事务封装
在数据库工具类编写的过程中,对事务的处理操作想避免各个原子操作的事务对象赋值重复操作,想对外暴露的方法为如下形式 public bool ExecuteTransition(Action Transi ...