aStar算法求第k短路
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短路的更多相关文章
- A* 算法求第 K 短路
一种具有 \(f(n)=g(n)+h(n)\) 策略的启发式算法能成为 A* 算法的充分条件是: 搜索树上存在着从起始点到终了点的最优路径. 问题域是有限的. 所有结点的子结点的搜索代价值 \(> ...
- A*算法的认识与求第K短路模板
现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...
- poj 2449(A*求第K短路)
题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...
- POJ 2449 求第K短路
第一道第K短路的题目 QAQ 拿裸的DIJKSTRA + 不断扩展的A* 给2000MS过了 题意:大意是 有N个station 要求从s点到t点 的第k短路 (不过我看题意说的好像是从t到s 可能是 ...
- POJ 2499 A*求第K短路
DES就是给你一个图.然后给你起点和终点.问你从起点到终点的第K短路. 第一次接触A*算法. 题目链接:Remmarguts' Date 转载:http://blog.csdn.net/mbxc816 ...
- A* 算法求第k短路径
A*算法是一类贪心算法,其可以用于寻找最优路径.我们可以利用A*算法来求第k短路径. 一条路径可以由两部分组成,第一部分是一个从出发到达任意点的任意路径,而第二部分是从第一部分的末端出发,到终点的最短 ...
- poj 2449 Remmarguts' Date 求第k短路 Astar算法
=.=好菜 #include <iostream> #include <cstdio> #include <string.h> #include <cstri ...
- ACM模板~求第k短路 ~~~A*+Dijkstra
#include <map> #include <set> #include <cmath> #include <ctime> #include < ...
- POJ 2449 Remmarguts' Date (K短路 A*算法)
题目链接 Description "Good man never makes girls wait or breaks an appointment!" said the mand ...
随机推荐
- 《转》OpenStack Live Migration
This post is based assumption that KVM as hypervisor, and Openstack is running in Grizzly on top of ...
- GCC中初始化函数是怎样被处理的?
本文译至: http://gcc.gnu.org/onlinedocs/gccint/Initialization.html 如我们所知,在GCC通过给代码追加__attribute__((const ...
- Spring中的FactoryBean
从SessionFactory说起: 在使用SSH集成开发的时候,我们有时候会在applicationContext.xml中配置Hibernate的信息,以下是配置SessionFactory的一段 ...
- qt宽字符串中文乱码(codec->toUnicode值得学习)
乱码原因: QT使用的是utf-8 简体中文版的windows操作系统及其应用软件默认都是ANSI/GBK编码.而且这里应该是宽字符串. 多字节ANISGB 宽字符UNICODE 多字节显示标准字符的 ...
- 【PHP SDK for OpenStack/Rackspace APIs】身份验证
在你使用php-opencloud之前必须先取得云服务提供商的身份验证.这是整个过程中最简单也是最让人沮丧的部分. 说它最简单是因为你只需要两部分信息: 云服务提供商的身份验证端点 用来身份验证的证书 ...
- Codeforces Round #275 (Div. 2) C - Diverse Permutation (构造)
题目链接:Codeforces Round #275 (Div. 2) C - Diverse Permutation 题意:一串排列1~n.求一个序列当中相邻两项差的绝对值的个数(指绝对值不同的个数 ...
- android自定义实现抽屉SlidingDrawer的功能
最近项目中需要实现上拉功能,首先想到的就是Android本身自带的抽屉SlidingDrawer,最后也实现了不过,出现的问题就是设置背景色问题,handler和content是两个不同的部分,这就造 ...
- swt,jface,rcp
//swt-jface-rcp,基本结构:display类,shell类,组件:widget窗口控件,control控件,composites面板,button,label,text文本框,list列 ...
- 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 ...
- Types of Windows
The Window's Real Estate Application's Instance A window is referred to as parent when it can be ...