博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang
阅读量:5172 次
发布时间:2019-06-13

本文共 2894 字,大约阅读时间需要 9 分钟。

        题目大意:给你一个有向图,并给你三个数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
#include
#include
#include
#include
#include
#include
#include
#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
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
, 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 ;}

 

 

转载于:https://www.cnblogs.com/pangblog/p/3347894.html

你可能感兴趣的文章
初识maven及其安装步骤!!
查看>>
Linux终端基本命令
查看>>
课后作业四
查看>>
希尔排序----java实现
查看>>
php常用header头信息收藏
查看>>
fenby C语言 P26
查看>>
阿里云开发者大会:资源加应用酝酿云存储变局
查看>>
[HNOI 2001]产品加工
查看>>
Top 10 Java Debugging Tips with Eclipse
查看>>
bzoj 4556: [Tjoi2016&Heoi2016]字符串
查看>>
HDU4287 字典树
查看>>
PHP中的时间
查看>>
团队绩效评估
查看>>
最活跃FPGA论坛推荐社区
查看>>
SecurityException: No read access to the texture data. Unity WWW
查看>>
java官网下载
查看>>
codeforce 702C Cellular Network 二分答案
查看>>
如何彻底禁用 werfalut.exe
查看>>
win 64 SSDT HOOK
查看>>
MongoDB(八)Mongodb——GridFS存储
查看>>