<font color=black size=4>K短路问题还是很普遍的,了解一下K短路很有必要,顺便学会A*的简单应用更好。
A*算法,是一种启发式搜索算法,我们可以自己设定一个估价函数,这样我们的搜索过程就会优先选择有更好的估价函数的点进行搜索。
在最短路中,A*的估价函数定义如下:f(p)=g(p)+h(p),g(p)表示当前从起始点s到点p的距离,而h(p)就是从终点到p的最短路距离,(暂且是最短路,因为k短路必须由最短路出发向前找的,每次都是除了上一次的最短路),则f(p)就意味着从起点s到当前路径p之后再走到终点t的最短路,这样,我们的每次扩展都是有方向的扩展,从而降低求解速度和降低搜索的状态数,并且保证不优于最优解的同时尽量靠近最优解。
思路到了,做法也必须跟上。我们用最短路来估价,这就要求对h(p)函数进行一个预处理,所以我们可以求出终点到各个点的最短路,作为h(p)值,再从s开始遍历k次,每次都以上一次为最短路,直到我们第k次到达终点,此时的路径长度就是k短路。
</font>
<font color=black size=4>
详细部分看下面几个模板题的代码。
(1)POJ2449
题目链接:https://vjudge.net/problem/POJ-2449
题目大意:给出一个图,然后给出一个起点个一个终点,求这两点间的第K短路。
本题中是可以走重复的路的,所以如果一张图中有一个环的话,无论求第几短路都是存在的。
也就是,样例询问的第二短路,就是先从1到2,再从2到1,再从1到2,结果为5+4+5=14
代码:</font>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
/*
POJ 2449 A*求k短路模板题
*/
const int maxn=1005;
const int maxm=500005;
const int INF=0x3f3f3f3f;
struct Edge
{
int u;
int v;
int next;
int w;
}edges[maxm],re_edges[maxm];//re_edges为反向边
struct ANode
{
int f,g,v;//分别对应f函数,g函数和v编号
bool operator <(const ANode