A*的概念主意在于估计函数,f(n)=g(n)+h(n),f(n)是估计函数,g(n)是n节点的当前代价,h(n)是n节点的估计代价;而实际中,存在最优的估计函数f'(n)=g'(n)+h'(n),那么显然我们在A*的估计中,h(n)<=h'(n),否则你将搜不到最优解;(g(n)>=g'(n)我还不怎么清楚为什么啊,大多数情况是g(n)=g'(n),这个可以不用管吧。。)

求s->t的第k短路,

dist[x]为x->t的最短路 (这个只要反向建边,然后一次spfa,求出任意点到t点的距离即可

那么点x的g(x)=到达当前点的花费

h(x) = dist[x] ,    可以知道h(x)=h'(x),所以可以保证搜到最优解。

每次出出队列的都是当前f(x)最小的点,

所以如果点x出队列, 那么就cnt[x]++,

当cnt[x]==k时,那么当前的f(x)就是第k短路,因为第一次出队列时,肯定是最短路上的点,第二次是次短路上的点,第k次,自然就是第k短路上的点了。

 #pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <iostream>
typedef __int64 LL;
const int INF = << ; /*
*/
const int N = + ;
struct Node
{
int from, to, dis, next;
}g[N*];
int head[N], e;
int dist[N];
bool vis[N];
int cnt[N];
void addEdge(int u, int v, int dis)
{
g[e].from = u;
g[e].to = v;
g[e].dis = dis;
g[e].next = head[u];
head[u] = e++;
} void spfa(int src, int n)
{
for (int i = ;i <= n;++i)
dist[i] = INF;
std::queue<int> q;
q.push(src);
dist[src] = ;
while (!q.empty())
{
int u = q.front(); q.pop();
vis[u] = false;
for (int i = head[u];i + ;i = g[i].next)
{
int v = g[i].to;
if (dist[v] > dist[u] + g[i].dis)
{
dist[v] = dist[u] + g[i].dis;
if (!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
}
void init()
{
e = ;
memset(head, -, sizeof(head));
}
void reverse()
{
memset(head, -, sizeof(head));
int te = e;
e = ;
for (int i = ;i < te;++i)
addEdge(g[i].to, g[i].from, g[i].dis);
}
struct Node2
{
int to;
int g;
bool operator<(const Node2&rhs)const
{
return g + dist[to] > rhs.g + dist[rhs.to];
}
};
/*
因为每次出队列的都是最短的, 所以该点是第几次出队列,就表示是该点到终点的第k短路
*/
int aStar(int src, int des, int k)
{
std::priority_queue<Node2> q;
Node2 cur, tmp;
cur.to = src;
cur.g = ;
q.push(cur);
while (!q.empty())
{
cur = q.top(); q.pop();
int u = cur.to;
cnt[u]++;
if (cnt[u] > k) continue;
if (cnt[u] == k)
return cur.g + dist[u];
for (int i = head[u];i + ;i = g[i].next)
{
int v = g[i].to;
tmp.to = v;
tmp.g = cur.g + g[i].dis;
q.push(tmp);
}
}
return -;
}
int main()
{
int n, m, src, des, k;
while (scanf("%d%d", &n, &m) != EOF)
{
init();
int u, v, dis;
for (int i = ;i <= m;++i)
{
scanf("%d%d%d", &u, &v, &dis);
addEdge(v, u, dis);
}
scanf("%d%d%d", &src, &des, &k);
spfa(des, n);
reverse();
if (src == des)k++;//如果起点等于终点,那么最短路其实是什么都不走
int ans = aStar(src, des, k);
printf("%d\n", ans);
}
return ;
}

aStar算法求第k短路的更多相关文章

  1. A* 算法求第 K 短路

    一种具有 \(f(n)=g(n)+h(n)\) 策略的启发式算法能成为 A* 算法的充分条件是: 搜索树上存在着从起始点到终了点的最优路径. 问题域是有限的. 所有结点的子结点的搜索代价值 \(> ...

  2. A*算法的认识与求第K短路模板

    现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...

  3. poj 2449(A*求第K短路)

    题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...

  4. POJ 2449 求第K短路

    第一道第K短路的题目 QAQ 拿裸的DIJKSTRA + 不断扩展的A* 给2000MS过了 题意:大意是 有N个station 要求从s点到t点 的第k短路 (不过我看题意说的好像是从t到s 可能是 ...

  5. POJ 2499 A*求第K短路

    DES就是给你一个图.然后给你起点和终点.问你从起点到终点的第K短路. 第一次接触A*算法. 题目链接:Remmarguts' Date 转载:http://blog.csdn.net/mbxc816 ...

  6. A* 算法求第k短路径

    A*算法是一类贪心算法,其可以用于寻找最优路径.我们可以利用A*算法来求第k短路径. 一条路径可以由两部分组成,第一部分是一个从出发到达任意点的任意路径,而第二部分是从第一部分的末端出发,到终点的最短 ...

  7. poj 2449 Remmarguts' Date 求第k短路 Astar算法

    =.=好菜 #include <iostream> #include <cstdio> #include <string.h> #include <cstri ...

  8. ACM模板~求第k短路 ~~~A*+Dijkstra

    #include <map> #include <set> #include <cmath> #include <ctime> #include < ...

  9. POJ 2449 Remmarguts' Date (K短路 A*算法)

    题目链接 Description "Good man never makes girls wait or breaks an appointment!" said the mand ...

随机推荐

  1. 《转》OpenStack Live Migration

    This post is based assumption that KVM as hypervisor, and Openstack is running in Grizzly on top of ...

  2. GCC中初始化函数是怎样被处理的?

    本文译至: http://gcc.gnu.org/onlinedocs/gccint/Initialization.html 如我们所知,在GCC通过给代码追加__attribute__((const ...

  3. Spring中的FactoryBean

    从SessionFactory说起: 在使用SSH集成开发的时候,我们有时候会在applicationContext.xml中配置Hibernate的信息,以下是配置SessionFactory的一段 ...

  4. qt宽字符串中文乱码(codec->toUnicode值得学习)

    乱码原因: QT使用的是utf-8 简体中文版的windows操作系统及其应用软件默认都是ANSI/GBK编码.而且这里应该是宽字符串. 多字节ANISGB 宽字符UNICODE 多字节显示标准字符的 ...

  5. 【PHP SDK for OpenStack/Rackspace APIs】身份验证

    在你使用php-opencloud之前必须先取得云服务提供商的身份验证.这是整个过程中最简单也是最让人沮丧的部分. 说它最简单是因为你只需要两部分信息: 云服务提供商的身份验证端点 用来身份验证的证书 ...

  6. Codeforces Round #275 (Div. 2) C - Diverse Permutation (构造)

    题目链接:Codeforces Round #275 (Div. 2) C - Diverse Permutation 题意:一串排列1~n.求一个序列当中相邻两项差的绝对值的个数(指绝对值不同的个数 ...

  7. android自定义实现抽屉SlidingDrawer的功能

    最近项目中需要实现上拉功能,首先想到的就是Android本身自带的抽屉SlidingDrawer,最后也实现了不过,出现的问题就是设置背景色问题,handler和content是两个不同的部分,这就造 ...

  8. swt,jface,rcp

    //swt-jface-rcp,基本结构:display类,shell类,组件:widget窗口控件,control控件,composites面板,button,label,text文本框,list列 ...

  9. spring-framework-3.2.4.RELEASE 综合hibernate-release-4.3.5.Final一个错误Caused by: java.lang.NoClassDefFound

    LZ一体化的今天spring-framework-3.2.4.RELEASE 综合hibernate-release-4.3.5.Final一个错误Caused by: java.lang.NoCla ...

  10. Types of Windows

    The Window's Real Estate   Application's Instance   A window is referred to as parent when it can be ...