题目大意:给你一个有向图,并给你三个数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. String[]和ArrayList和LinkedList区别

    String[]和ArrayList和LinkedList区别 参考文档如下: http://www.blogjava.net/flysky19/articles/92775.html http:// ...

  2. mockito学习笔记

    mockito http://mockito.github.io/mockito/docs/current/org/mockito/Mockito.html

  3. mysql怎么限制某些查询语句的执行?

    mysql怎么限制某些查询语句的执行? 比如某些sql语句执行时间很长,超过10s,怎么样超过10s就不让其执行? 后续更新中...

  4. tomcat startup.sh提示java.lang.OutOfMemoryError: PermGen space

    JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m"if [ -z "$LOGGING_MANAGER& ...

  5. Entity Framework 新增实体,新增抽象实体

    抽象实体不能new 抽象类:人,实体类:学生 人 p_人= new 学生();   添加数据,学生和人都添加 抽象类可以提供一个抽象的方法,但是并没有实现,类似接口,但又不同于接口.子类继承父类时必须 ...

  6. git add相关

    git add -A stages All git add . stages new and modified, without deleted git add -u stages modified ...

  7. 1.Tomcat配置

    1.启动 解压缩安装包后,点击startup.bat,保持控制台窗口开启 浏览器中输入http://localhost:8080 后看到启动界面则表示启动成功 点击shutdown.bat则关闭Tom ...

  8. Caused by: java.lang.NullPointerException, java.lang.reflect.InvocationTargetExc

    java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native M ...

  9. 武汉科技大学ACM :1007: A+B for Input-Output Practice (VII)

    Problem Description Your task is to Calculate a + b. Input The input will consist of a series of pai ...

  10. 如何在Eclipse中给main方法加参数

    在main方法中有一个args参数,那么如何给args参数赋值呢? public class TestMain { public static void main(String[] args) { f ...