题目大意:给你一个有向图,并给你三个数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的更多相关文章

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

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

  2. poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)

    http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  3. 图论(A*算法,K短路) :POJ 2449 Remmarguts' Date

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 ...

  4. poj 2449 Remmarguts' Date (k短路模板)

    Remmarguts' Date http://poj.org/problem?id=2449 Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  5. poj 2449 Remmarguts' Date 第k短路 (最短路变形)

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 33606   Accepted: 9116 ...

  6. POJ 2449 Remmarguts' Date (第k短路径)

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions:35025   Accepted: 9467 ...

  7. poj 2449 Remmarguts' Date(K短路,A*算法)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013081425/article/details/26729375 http://poj.org/ ...

  8. POJ 2449 Remmarguts' Date ( 第 k 短路 && A*算法 )

    题意 : 给出一个有向图.求起点 s 到终点 t 的第 k 短路.不存在则输出 -1 #include<stdio.h> #include<string.h> #include ...

  9. POJ 2449 Remmarguts' Date(第k短路のA*算法)

    Description "Good man never makes girls wait or breaks an appointment!" said the mandarin ...

随机推荐

  1. Using Notepad++ to Execute Oracle SQL

    原文链接:http://www.toadworld.com/products/toad-for-oracle/b/weblog/archive/2013/08/21/using-notepad-to- ...

  2. zookeeper主要使用场景

    场景一:有一组服务器向客户端提供某种服务,我们希望客户端每次请求服务端都可以找到服务端集群中某一台服务器,这样服务端就可以向客户端提供客户端所需的服务.对于这种场景,我们的程序中一定有一份这组服务器的 ...

  3. Oracle数据库锁表的查询方法以及解锁的方法

    1,锁表语句简单查询方法   select t2.username,t2.sid,t2.serial#,t2.logon_time from v$locked_object t1,v$session ...

  4. RMAN-06496: must use the TO clause when the database is mounted or open

    一:问题描述 备份控制文件时报错: RMAN> restore controlfile from '/home/oracle/backup/PROD_32_20140829.bak'; Star ...

  5. 你好,C++(28)用空间换时间 5.2 内联函数 5.3 重载函数

    5.2  内联函数 通过5.1节的学习我们知道,系统为了实现函数调用会做很多额外的幕后工作:保存现场.对参数进行赋值.恢复现场等等.如果函数在程序内被多次调用,且其本身比较短小,可以很快执行完毕,那么 ...

  6. mysql innodb myisam 主要区别与更改方法

    一.主要区别 1.事务处理 innodb 支持事务功能,myisam 不支持. Myisam 的执行速度更快,性能更好.   2.select ,update ,insert ,delete 操作   ...

  7. jquery中的replaceWith()和html()有什么区别?

    区别在于,html()会替换指定元素内部的HTML,而replaceWith()会替换元素本身及其内部的HTML. 例子: 1 <div id="myid" /> 1 ...

  8. jquery判断滚动条到底

    $(document).scroll(function(){ var dHeight = $(document).height(); var wHeight = $(window).height(); ...

  9. php 异常捕获

    1 首先是try,catch <?php $path = "D:\\in.txt"; try //检测异常 { file_open($path); } catch(Excep ...

  10. Python3 如何优雅地使用正则表达式(详解三)

    模块级别的函数 使用正则表达式也并非一定要创建模式对象,然后调用它的匹配方法.因为,re 模块同时还提供了一些全局函数,例如 match(),search(),findall(),sub() 等等.这 ...