POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang
题目大意:给你一个有向图,并给你三个数s、t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径。如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度。
解题思路:这道题是一道简单的启发式搜索题目。而启发式搜索中A星算法是比较好理解的。A星算法中需要用到一个估价函数:f(n) = g(n)+ h(n)。其中,g(n)是当前量,h(n)是估计量,两者之和 f(n) 是估计值 。在这道题中,g(n)是从起点 s 到 点n 的已走距离,h(n)是从点n 到终点 t 的最短距离(dis[ n ]) 。每当我们走到一个点 tn 时 ,就计算出此时 tn 的g(tn) 、 h(tn)和 f(tn),把 tn 的这些信息压入一个队列,然后下一步选取队列中 f 值最小的节点作为下一步搜索的起点,如此反复,当我们第k次搜索到终点 t 时 ,这时g(t)的值就是我们要求的值。
Ps:这里我们需要用到优先队列,并且要注意:因为必须离开 s 点再返回,所以,当 s == t 时 ,k ++ 。
请看代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<vector>
#include<cstdio>
#include<queue>
#define mem(a , b) memset(a , b , sizeof(a))
using namespace std ;
inline void RD(int &a)
{
a = 0 ;
char t ;
do
{
t = getchar() ;
}
while (t < '0' || t > '9') ;
a = t - '0' ;
while ((t = getchar()) >= '0' && t <= '9')
{
a = a * 10 + t - '0' ;
}
}
inline void OT(int a)
{
if(a >= 10)
{
OT(a / 10) ;
}
putchar(a % 10 + '0') ;
}
const int N = 1005 ;
const int M = 1e5 + 5 ;
const int INF = 0x7fffffff ;
struct Edge
{
int adj ;
int d ;
int next ;
} E[M * 3] ;
int head[N] ;
int headN[N] ; // 反向图
int dis[N] ;
bool inq[N] ;
int s , t , k ;
int n , m ;
int ce ;
void chu()
{
mem(head , - 1) ;
mem(headN , -1) ;
mem(inq , 0) ;
ce = 0 ;
}
void init()
{
chu() ;
int i ;
for(i = 0 ; i < m ; i ++)
{
int a , b , c ;
scanf("%d%d%d" , &a , &b , &c) ;
ce ++ ;
E[ce].adj = b ;
E[ce].d = c ;
E[ce].next = head[a] ;
head[a] = ce ; ce ++ ;
E[ce].adj = a ;
E[ce].d = c ;
E[ce].next = headN[b] ;
headN[b] = ce ;
}
scanf("%d%d%d" , &s , &t , &k) ;
}
queue<int> q ;
void spfa() // 计算 dis
{
while (!q.empty()) q.pop() ;
q.push(t) ;
inq[t] = true ;
int v ;
while (!q.empty())
{
v = q.front() ;
q.pop() ;
inq[v] = false ;
int i ;
for(i = headN[v] ; i != -1 ; i = E[i].next)
{
int tv = E[i].adj ;
int td = E[i].d ;
if(dis[v] + td < dis[tv])
{
dis[tv] = dis[v] + td ;
if(!inq[tv])
{
q.push(tv) ;
inq[tv] = true ;
}
}
}
}
}
struct F
{
int Node ;
int f ;
int g ;
int h ;
};
struct cmp
{
bool operator () (F a , F b)
{
if(a.f == b.f)
{
return a.g > b.g ;
}
return a.f > b.f ;
}
} ;
priority_queue<F, vector<F> , cmp> mq ;
int SP() // A星 算法
{
if(s == t) k ++ ;
while (!mq.empty()) mq.pop() ; // 注意队列要清空
int cnt = 0 ;
F u ;
u.Node = s ;
u.g = 0 ;
u.h = dis[s] ;
u.f = u.g + u.h ;
mq.push(u) ;
while (!mq.empty())
{
F v = mq.top() ;
if(v.Node == t)
{
cnt ++ ;
if(cnt == k)
{
return v.g ;
}
}
mq.pop() ;
int i ;
for(i = head[v.Node] ; i != -1 ; i = E[i].next)
{
int tv = E[i].adj ;
int td = E[i].d ;
F tmp ;
tmp.Node = tv ;
tmp.g = v.g + td ;
tmp.h = dis[tv] ;
tmp.f = tmp.g + tmp.h ;
mq.push(tmp) ;
}
}
return -1 ; // 注意:因为此图是有向图,所以K短路可能不存在!!!
}
void solve()
{
int i ;
for(i = 1 ; i <= n ; i ++)
{
dis[i] = INF ;
}
dis[t] = 0 ;
spfa() ;
if(dis[s] == INF)
{
puts("-1") ;
return ;
}
else
{
printf("%d\n" , SP()) ;
}
}
int main()
{
while (scanf("%d%d" , &n , &m) != EOF)
{
init() ;
solve() ;
}
return 0 ;
}
POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang的更多相关文章
- POJ 2449 Remmarguts' Date (K短路 A*算法)
题目链接 Description "Good man never makes girls wait or breaks an appointment!" said the mand ...
- poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)
http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
- 图论(A*算法,K短路) :POJ 2449 Remmarguts' Date
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 25216 Accepted: 6882 ...
- poj 2449 Remmarguts' Date (k短路模板)
Remmarguts' Date http://poj.org/problem?id=2449 Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
- poj 2449 Remmarguts' Date 第k短路 (最短路变形)
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 33606 Accepted: 9116 ...
- POJ 2449 Remmarguts' Date (第k短路径)
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions:35025 Accepted: 9467 ...
- poj 2449 Remmarguts' Date(K短路,A*算法)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013081425/article/details/26729375 http://poj.org/ ...
- POJ 2449 Remmarguts' Date ( 第 k 短路 && A*算法 )
题意 : 给出一个有向图.求起点 s 到终点 t 的第 k 短路.不存在则输出 -1 #include<stdio.h> #include<string.h> #include ...
- POJ 2449 Remmarguts' Date(第k短路のA*算法)
Description "Good man never makes girls wait or breaks an appointment!" said the mandarin ...
随机推荐
- python 下的数据结构与算法---8:哈希一下【dict与set的实现】
少年,不知道你好记不记得第三篇文章讲python内建数据结构的方法及其时间复杂度时里面关于dict与set的时间复杂度[为何访问元素为O(1)]原理我说后面讲吗?其实就是这篇文章讲啦. 目录: 一:H ...
- Objective-C学习篇10—NSDate与NSDateFormatter
NSDate NSDate 时间类,继承自NSObject,其对象表示一个时间点 NSDate *date = [NSDate date]; NSLog(@"date = %@", ...
- Mac系统配置多个git账号
1.进入ssh目录 #cd ~/.ssh/ 2.用ssh-keygen命令生成一组新的id_rsa_new和id_rsa_new.pub #ssh-keygen -t rsa -C"new ...
- 批处理备份和恢复mysql数据库
备份 set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%" md "D: ...
- QT5-控件-QProgressBar-进度条-用来做下载进度,文件读取进度还不错
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QProgressBar> ...
- Y - Design T-Shirt(第二季水)
Description Soon after he decided to design a T-shirt for our Algorithm Board on Free-City BBS, XKA ...
- CodedDFS日志配置
本文根据Log4j的配置属性,编写了用于记录BMBR编码的日志 author: zyumeng Blog: [url] http://www.cnblogs.com/zyumeng/ [/url] 利 ...
- Solr自动生成ID
在Solr中,每一个索引,都要有一个唯一的ID,类似于关系型数据库表中的主键.为了方便创建索引,需要配置自动生成的ID,即UUID. 一.配置schema.xml文件 添加uuid字段类型,修改字段i ...
- 转: fscanf()函数详解
以前解析有规律的文件的时候要么用正则表达式,要么就是傻傻的自己写程序来解析有规律的文件.今天突然发现c的库函数中有一个现成的可以解析有规律的文件的函数,就是fscanf()函数.哎 以前自己做了这么多 ...
- Vector3.Dot 与Vector3.Cross
Vector3.Dot(点积) : 点积的计算方式为: a·b=|a|·|b|cos<a,b>; 其中<a,b>和<b,a> 夹角不分顺序; 物理学中点积用来计算 ...