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)的更多相关文章

  1. P2483 【模板】k短路([SDOI2010]魔法猪学院)

    题目背景 感谢@kczno1 @X_o_r 提供hack数据 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界 ...

  2. bellman-ford算法求K短路O(n*m),以及判负环O(n*m)

    #include<iostream> #include<algorithm> #include<cstring> using namespace std; cons ...

  3. Luogu P2483 【模板】k短路([SDOI2010]魔法猪学院)

    说实话,看到这道题的洛谷评级我傻了(传说中的最高难度) 然后看完题目才确定这真的是一道k短路的裸题. 也就敲了个A*吧,15分钟竟然没有调试一遍过. 欧洲玄学. 看题目,主要是找几条从1走到n的路加起 ...

  4. BZOJ 1975 魔法猪学院(A*求K短路)

    显然每次贪心的走最少消耗的路径即可.那么也就是找出最短路,次短路,,,K短路之后消耗E的能量的最多的路径条数. 也就是裸的A*算法. #include <bits/stdc++.h> us ...

  5. 【洛谷 P2483】 【模板】k短路([SDOI2010]魔法猪学院)(A*)

    题目链接 优先队列bfs第一次出队就是最短路,那么显然第k次出队就是k短路 ?????????????????????????????? 书上写的 但是直接优先队列bfs会T,所以用A*优化就行,估价 ...

  6. A*算法求K短路模板 POJ 2449

    #include<cstdio> #include<queue> #include<cstring> using namespace std; const int ...

  7. 【模板】K短路 A-star

    引理:当一个状态对应的节点第K次从堆中取出时,该状态对应的当前代价是从起点到该点的第K优解. 代码如下 /* POJ2449 */ #include <cstdio> #include & ...

  8. luogu2483 【模板】k短路([SDOI2010]魔法猪学院)

    模板题 #include <iostream> #include <cstring> #include <cstdio> #include <queue> ...

  9. 第K短路模板【POJ2449 / 洛谷2483 / BZOJ1975 / HDU6181】

    1.到底如何求k短路的? 我们考虑,要求k短路,要先求出最短路/次短路/第三短路……/第(k-1)短路,然后访问到第k短路. 接下来的方法就是如此操作的. 2.f(x)的意义? 我们得到的f(x)更小 ...

随机推荐

  1. Nexus 安装运维手册

    1. Nexus 安装与配置 1.1 下载Nexus 登录https://www.sonatype.com/download-oss-sonatype,下载最新的Nexus版本. 我这里使用的是nex ...

  2. Vue中你可能认为是bug的情况原来是这样的

    前言 我们知道Vue框架剧本双向数据绑定功能,在我们使用方便的同时,还有一些细节问题我们并不知道,接下来一起探讨一些吧 双向数据绑定 js变量改变影响页面 页面改变影响js变量 Vue2是如何做到数据 ...

  3. Python json格式处理

    Python json格式处理 首先放一段代码 import requests import jsonpath import json f=open('ip.txt','r',encoding='ut ...

  4. mac item2的快捷键

    https://juejin.im/entry/58fac23fb123db4449071c99 听说这个工具可以解决,iterm2的整句翻译的问题.一致找不到免费的破解版本. Myna for Go ...

  5. 计算机网络 From Mr.Liu

    引言 本博客摘自Mr.Liu,原帖请点击这里. 感谢Mr.Liu,这个文章很充分的描述了计算机网络的核心知识点. 我还在学习中,所以没有进行自己的转述.图片因为是copy代码而没有获得,想看更详尽的, ...

  6. Shiro -- (三) 自定义Realm

    简介: Realm:域,Shiro 从从 Realm 获取安全数据(如用户.角色.权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定 ...

  7. 802.11 MAC基础

    MAC(媒介访问控制层)位于各式物理层之上,控制数据的传输.它负责核心成帧操作以及与有线骨干网络之间的交互. 802.11采用载波监听多路访问/冲突避免(CSMA/CA)机制来控制对传输媒介的访问. ...

  8. 得心应用的Vue高级技巧---vue中文社区

    1,require.context()一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多 ...

  9. 通过sql的stuff 把一列几行的记录拼接在一行一个字段

    ---通过sql的stuff 把一列几行的记录拼接在一行一个字段 select FID,a.FCustomerID as 工地ID , 应验收节点 = (stuff((select ',' + isn ...

  10. opencv —— floodFill 漫水填充法 实现证件照换背景

    漫水填充:floodFill 函数 简单来说,漫水填充就是自动选中与种子像素相连的区域,利用指定颜色进行区域颜色填充.Windows 画图工具中的油漆桶功能和 Photoshop 的魔法棒选择工具,都 ...