题目大意:给你一个有向图,并给你三个数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. ASP.NET-FineUI开发实践-9(二)

    其实我也不会,老实教人学怕误人子弟,但是抱着毁人不倦的精神还是糊弄糊弄个别小白吧,最起码能加点原创. 下面以表单为例,打开官方项目,版本为FineUI_4.1.1,打开form_compare页,右键 ...

  2. IE7append新的元素自动补充完整路径

    在IE7下,进行append操作时,会把像<img />的src补成完整路径.对于上传到临时目录的图片,提交到后台要进行路径判断的情形要十分注意.

  3. 【SQL】查询语句中in和exists的区别

    in in可以分为三类: 一. 形如select * from t1 where f1 in ( &apos:a &apos:, &apos:b &apos:),应该和 ...

  4. javascript DOM对象转jquery对象

    首先,假设一种情形:要在HTML文件中为一个select对象添加一个函数,这个函数的名字叫dynamic_change(this),当select的option被改变的时候调用onchange事件来处 ...

  5. IIS下图片防盗连设置详解

    小站只有100个IIS,盗链后经常是连主页都打不开,就想着弄个图片防盗链,在网上找了一下资料,正则表达式的写法啊,ISAPI_REWRITE基本配置啊等等,找来啃了一天终于发现有三个方法实现. 第一. ...

  6. 一个Div在BOdy中上下左右居中

    在body中让一个DIv居中 上下左右 <body> <div style=" width:800px; height:500px; position:absolute; ...

  7. Nvidia显卡怎样查看显存大小及硬件相关信息

    在电脑上安装Nvidia显卡驱动,平时也会通过Nvidia控制面板来查看显示显存位宽及宽带.显示显存容量和显示显存芯片信息等等,那么该如何查看Nvidia显存大小以及Nvidia硬件相关信息呢? 1. ...

  8. 转:Spine.JS+Rails重客户端Web应用技术选型思路:『风车』架构设计

    原文来自于:http://www.infoq.com/cn/articles/fengche-co-architecture 风车这个项目开始于 2011 年 11 月份,之前叫做 Pragmatic ...

  9. js 比较日期大小

    //1获取当前时间 var curTime = new Date(); //2把字符串格式转换为日期类 var startTime = new Date(Date.parse(kc.begintime ...

  10. hosting company 的 mail , localhost send 不到

    不是每一家 hosting 的 mail 都运行你在本地连接发email的. 或许是因为安全的顾虑吧. 总之下次如果发现在本地发不出email,可以试试看 upload to server. 过往经验 ...