POJ_2449

一开始我的思路就是把图上每个点搞一个容量不小于K的最大堆和最小堆,最小堆用于取当前该节点的第某短路值,最大堆用来保存前K小的最短路。

最后为了每次能查询全局最小值,再把N个点放到一个线段树(最小堆)上即可,剩下的工作就是进行dij的过程了,当访问终点的次数达到第K次时break即可,这时就是第K短路的值了。

但这样会TLE,所以还是要用A*算法。

感觉A*就像是个优先级队列,从这个角度讲,dij本来也是A*算法,只不过其估价函数就等于起点到该点的最短距离。

而这个题目需要变一下估价函数,设g[i]为由某条路线从S到i点的路径长度,d[i]表示i点到T的最短路,那么我们把g[i]+d[i]作为估价函数,而其他的步骤和dij都是一样的,在第K次搜到终点的时候退出即可。

这样做相比用g[i]作为估计函数是更好的。首先g[i]+d[i]实际反映的是一条路径的长度,是从路径的角度着眼的。同时,d[i]表示的是当前走了g[i]到达i点的情况下,最快还需要走多少到达终点,那么如果g[i]+d[i]都不能作为K短路之内的路径的话,那么我们自然不用再从g[i]开始拓展了,因为这样拓展的话最终长度至少是g[i]+d[i],这样就完成了一个剪枝。

至于为什么第K次搜到终点的时候退出即可,这个不难理解。因为对任意一个点i,d[i]是定值,那么第K小的g[i]+d[i]中的g[i]自然就是第K小的g[],也就是第K短路。

#include<stdio.h>#include<string.h>#define MAXD 1010#define MAXM 100010#define MAXT 2050#define MAXK 1010#define INF 0x3f3f3f3fint DI, DO, N, M, K, S, T, first[MAXD], next[MAXM], v[MAXM], w[MAXM], tree[MAXT], e;int nf[MAXD], nn[MAXM], nv[MAXM], nw[MAXM], d[MAXD];struct Tree{int dis, min, min_tree[MAXT], max_tree[MAXT], a[MAXT];void init()    {int i;        min = dis = INF;for(i = 0; i < DI; i ++)        {            min_tree[i + DI] = max_tree[i + DI] = i;            a[i] = INF;        }for(i = DI - 1; i > 0; i --)        {            min_tree[i] = min_tree[i << 1];            max_tree[i] = max_tree[i << 1];        }    }void update_min(int i)    {for(; i ^ 1; i >>= 1)            min_tree[i >> 1] = a[min_tree[i]] < a[min_tree[i ^ 1]] ? min_tree[i] : min_tree[i ^ 1];    }void update_max(int i)    {for(; i ^ 1; i >>= 1)            max_tree[i >> 1] = a[max_tree[i]] > a[max_tree[i ^ 1]] ? max_tree[i] : max_tree[i ^ 1];    }int Insert(int x, int i)    {int k = max_tree[1];if(x < a[k])        {            a[k] = x, update_max(DI + k), update_min(DI + k);if(x < min)            {                min = x;                dis = min - d[i];return 1;            }        }return 0;    }void Delete(int i)    {int k = min_tree[1];        a[k] = INF, update_min(DI + k);        min = a[min_tree[1]];        dis = min - d[i];    }}t[MAXT];void add(int x, int y, int z){    w[e] = z, v[e] = y;    next[e] = first[x], first[x] = e;    nw[e] = z, nv[e] = x;    nn[e] = nf[y], nf[y] = e;    ++ e;}void init(){int i, j, k, x, y, z;for(DO = 1; DO <= N; DO <<= 1);    memset(first + 1, -1, sizeof(first[0]) * N);    memset(nf + 1, -1, sizeof(nf[0]) * N);    e = 0;for(i = 0; i < M; i ++)    {        scanf("%d%d%d", &x, &y, &z);        add(x, y, z);    }    scanf("%d%d%d", &S, &T, &K);for(DI = 1; DI < K; DI <<= 1);}void dij_update(int i){for(; i ^ 1; i >>= 1)        tree[i >> 1] = d[tree[i]] < d[tree[i ^ 1]] ? tree[i] : tree[i ^ 1];}void dij(){int i, j, k, x;    d[0] = INF;    memset(tree + 1, 0, sizeof(tree[0]) * (DO << 1));    memset(d + 1, 0x3f, sizeof(d[0]) * N);    d[T] = 0, tree[T + DO] = T, dij_update(T + DO);while(x = tree[1])    {for(i = nf[x]; i != -1; i = nn[i])if(d[x] + nw[i] < d[nv[i]])            {                d[nv[i]] = d[x] + nw[i];                tree[nv[i] + DO] = nv[i], dij_update(nv[i] + DO);            }        tree[x + DO] = 0, dij_update(x + DO);    }}void update(int i){for(; i ^ 1; i >>= 1)        tree[i >> 1] = t[tree[i]].min < t[tree[i ^ 1]].min ? tree[i] : tree[i ^ 1];}void solve(){int i, j, k, cnt, x, y, z;    dij();    memset(tree + 1, 0, sizeof(tree[0]) * (DO << 1));for(i = 0; i < DO; i ++)    {        t[i].init();        tree[i + DO] = i;    }for(i = DO - 1; i > 0; i --)        tree[i] = tree[i << 1];    t[S].Insert(d[S], S), update(S + DO);    cnt = S == T ? -1 : 0;while(t[x = tree[1]].min != INF)    {if(x == T)        {if(++ cnt == K)break;        }for(i = first[x]; i != -1; i = next[i])if(t[v[i]].Insert(t[x].dis + w[i] + d[v[i]], v[i]))                update(v[i] + DO);        t[x].Delete(x), update(x + DO);    }if(cnt == K)        printf("%d\n", t[tree[1]].dis);else        printf("-1\n");}int main(){while(scanf("%d%d", &N, &M) == 2)    {        init();        solve();    }return 0;}

POJ 2449 Remmarguts' Date相关推荐

  1. POJ 2449 Remmarguts' Date [第k短路]

    Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu Descripti ...

  2. poj 2449 Remmarguts' Date 启发式搜索 A*算法

    做这个题算是学了学spfa算法,一开始感觉spfa和dij好像:dij找最小点松弛,spfa就是一个一个的松弛,松到不能松. 求S到T的第K短路 思路:这个算法的思路是从源点S优雅的暴力跑bfs,用优 ...

  3. POJ 2449 Remmarguts' Date(第K短路 + A* + 最短路)题解

    题意:找出第k短路,输出长度,没有输出-1 思路:这题可以用A*做.A*的原理是这样,我们用一个函数:f = g + h 来表示当前点的预期步数,f代表当前点的预期步数,g代表从起点走到当前的步数,h ...

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

    link:https://vjudge.net/problem/POJ-2449 前面输入与大多最短路题相同 最后一行输入s,t,k 求从s到t的第K短路 wiki link: https://en. ...

  5. POJ - 2449 Remmarguts' Date(第k短路:spfa+A*)

    题目链接:点击查看 题目大意:给出一个有向图,求第k短路 题目分析:偷学了一波A*,本来以为是多难的算法,其实就是bfs+优先队列的升级版,之前看的那些博客写的都太深奥了,以至于看了一半啥都没看懂然后 ...

  6. 【POJ】【2449】Remmarguts' Date

    K短路/A* 经(luo)典(ti) K短路题目= = K短路学习:http://www.cnblogs.com/Hilda/p/3226692.html 流程: 先把所有边逆向,做一遍dijkstr ...

  7. Poj2449 Remmarguts' Date 【A*搜索】K短路

    http://poj.org/problem?id=2449 A*搜索求K短路. #include <cstdio> #include <cstring> #include & ...

  8. Remmarguts' Date(POJ2449+最短路+A*算法)

    题目链接:http://poj.org/problem?id=2449 题目: 题意:求有向图两点间的k短路. 思路:最短路+A*算法 代码实现如下: 1 #include <set> 2 ...

  9. poj 2449 A*求k短路

    A*的入门题目,需要注意的是当图中只有一个点的时候k短路是不存在的. 1 #include <iostream> 2 #include <cstring> 3 #include ...

最新文章

  1. Kotlin setText 使用
  2. f2 柱状图滚动 钉钉小程序_钉钉小程序图表库AntV - F2 使用总结
  3. ASP.NET中 Calendar(日期控件)的使用
  4. 小红帽怎样装图形化界面_linux安装图形化界面
  5. 基本数据类型和引用数据类型作为参数时候的问题
  6. 动态多维数组在 VC 中的应用
  7. apc220使用心得
  8. 12月7日 第二冲刺周期个人站立会议内容报告(第七天)
  9. Python对数列进行全排列
  10. element js 包含字符_selenium3.x(10)js弹框处理
  11. 【渝粤教育】广东开放大学 数据结构 形成性考核 (30)
  12. Linux:chmod命令-修改文件或目录的权限
  13. JVM—内存分配与回收策略
  14. 写了Bug,误执行 rm -fr /*,我删删删删库了,要跑路吗?| 原力计划
  15. 1102. Invert a Binary Tree (25)-PAT甲级真题
  16. 为什么用Java——一个来自Python阵营的程序员告诉你
  17. 汇编 LED驱动 烧写bin文件到SD卡
  18. 如何理解软件测试质量,我对测试总结报告和质量分析报告的理解
  19. 三天打鱼两天晒网C++
  20. Exploratory Social Network Analysis with Pajek(第三版)11

热门文章

  1. k2p一直亮红灯搜不到信号_周迅感情亮红灯?真离了!?亮红灯英文是red light ?red 对了,但不用 light!...
  2. 计算机软件服务板块,信息技术板块
  3. 高精度计算PI值 C语言 思路,高精度计算pi
  4. jsp+java bean+mysql数据库进行分页显示
  5. 安卓学习笔记15:使用安卓应用程序资源
  6. 【codevs1037】取数游戏,博弈
  7. 【BZOJ1010】【codevs1319】玩具装箱,斜率优化DP
  8. 网络计算机热词,2017年的首个网络热词就这样被刷屏了!
  9. 【英语学习】【Daily English】U07 Restaurant L02 I don't think this is what I ordered?
  10. 前端直播与SRS视频流服务的使用