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 ...
随机推荐
- u-boot的nand驱动写过程分析
从命令说起,在u-boot输入下列命令: nand write 40008000 0 20000 命令的意思是将内存0x40008000开始的部分写入nand,从nand地址0开始写,写入长度是0x2 ...
- ASP.NET - 分页
效果: SQL-存储过程(Paging): ROW_NUMBER() over(order by MessageDateTime desc) 其中的 MessageDateTime desc 代表的 ...
- Android和java平台 DES加密解密互通程序及其不能互通的原因
网上的demo一搜一大堆,但是,基本上都是一知半解(包括我).为什么呢?我在尝试分别在两个平台加密的时候,竟然发现Android DES 加密和java DES加密的程序不能互通.就是加密的结果不一样 ...
- 在VC++中启用内存泄露检测
检测内存泄漏的主要工具是调试器和 CRT 调试堆函数.若要启用调试堆函数,请在程序中包括以下语句: #define CRTDBG_MAP_ALLOC#include <stdlib.h># ...
- Delphi主窗口任务栏菜单的问题(转发WM_SYSCOMMAND到Application)
Delphi的VCL框架在创建应用时TApplication是一个自动创建的隐藏窗口,其它创建的窗口是自动以该窗口为窗口,这就导致创始的主窗口在任务栏的系统菜单只有三项,只要在主窗口的Create事件 ...
- [docker]docker的四种网络方式
声明: 本博客欢迎转发,但请保留原作者信息! 博客地址:http://blog.csdn.net/halcyonbaby 内容系本人学习.研究和总结,如有雷同,实属荣幸! bridge方式(默认) H ...
- make 2>&1 | tee log.txt之小析
前言 接触过linux的人,或多或少都会了解一点make 2>&1 | tee log.txt这个命令. 1. make是什么? make是linux下一个非常强大的命令,简单点就是你要 ...
- drupal form 中图片上传
1.创建url 链接到form $items['qianfeng/add'] = array( 'title' => t('加入信息'), 'page callback' =&g ...
- 管理处理器的亲和性(affinity)
管理处理器的亲和性(affinity) 管理处理器的亲和性(affinity)
- [华为机试练习题]50.求M的N次方的最后三位
题目 描写叙述: 正整数M 的N次方有可能是一个很大的数字,我们仅仅求该数字的最后三位 例1: 比方输入5和3 ,5的3次方为125.则输出为125 例2: 比方输入2和10 2的10次方为1024 ...