一道来自POJ2449的题,它融合了单源点最短路算法、启发式搜索,让我们对“启发式”有更深的理解和体会。Wow!

·英文题,述大意:

      读入n,m(n<=1000,m<=100000),表示节点数和边数,接下来m行输入每条有向边的端点和权值。之后输入起点、终点和K。求出第K短路的长度,没有就输出-1.(注意:①一条起点到终点的路径上可以包含多个相同点,起点终点也可以包含多个!②起点和终点可以重合,而且最短路就是0)

·分析:

      首先就是要搜索。不过搜索的判断依据要做变化,决不是以前简单的dis比大小了。说专业点就是尝试要构造启发式f()函数,说通俗点,就是尝试更改搜索队列的优先级关键字信息,使得满足条件。

       在搜索里,由于不是找最短路,所以vis[]荡然无存。我们需要一种优先队列,使得当前弹出的是目前最短路。如何寻到第K短路:找到一条最短路,用cnt记一下,表示当前找到的起点到终点的第cnt短路,直至K==cnt。

       美妙之处在于怎样快速找出当前搜索到的点中,顺着哪一个点先走下去会得到一条到终点的当前最短路。也就是我们要具有一种预测未来的能力,它不同于正常的最短路思路:不断尝试,不断贪心。预测未来能力能够知道按某一个点先开始展开搜索,它一定在未来先以最短路抵达终点。

        我们不具有预测未来的能力,所以只能预处理。预处理以终点为单源点的最短路dis数组。那么在我们使用搜索的时候,只需要将起点到当前点距离与当前点和终点的最短路距离的和作为比较关键字存入优先队列中,这样一来每一步优先队列都为您维护着最有希望的那个点(the most promising point)。

       在代码来到之前有一个申明:虽说vis数组已经不在了,但是大米饼依旧用它的名字在搜索中表示当前点被访问的次数(因为每个点最多被访问K次)

 #include<stdio.h>
#include<queue>
#include<cstring>
#define go(i,a,b) for(int i=a;i<=b;i++)
#define fo(i,a,x) for(int i=a[x],v=e[i].v;i;i=e[i].next,v=e[i].v)
#define inf 100000000
using namespace std;const int N=;struct E{int v,next,w;}e[N*N*];
struct Kth{int u,f;bool operator<(const Kth& a)const{return f>a.f;}};
int n,m,head[N],back[N],k=,S,T,K,dis[N],ans=-;
void ADD(int u,int v,int w,int* H){e[k]=(E){v,H[u],w};H[u]=k++;}
void SPFA()
{
queue<int>q;bool inq[N]={};go(i,,n)dis[i]=inf;dis[T]=;q.push(T);
while(!q.empty())
{
int u=q.front();q.pop();inq[u]=;
fo(i,back,u)if(dis[u]+e[i].w<dis[v]){
dis[v]=dis[u]+e[i].w;!inq[v]?q.push(v),inq[v]=:;}
}
}
void BFS()
{
if(dis[S]>=inf)return;priority_queue<Kth>q;
int vis[N]={};q.push((Kth){S,dis[S]});K+=S==T;
while(!q.empty())
{
Kth p=q.top();q.pop();int u=p.u;vis[u]++;
if(vis[T]==K){ans=p.f;return;}fo(i,head,u)if(vis[v]<K)
q.push((Kth){v,p.f-dis[u]+e[i].w+dis[v]});
}
}
int main(){scanf("%d%d",&n,&m);go(i,,m){int u,v,w;scanf("%d%d%d",&u,&v,&w);
ADD(u,v,w,head),ADD(v,u,w,back);}scanf("%d%d%d",&S,&T,&K);
SPFA();BFS();printf("%d\n",ans);return ;
}//Paul_Guderian

I love you!always!Tme is nothing——The Time Traveller,Henry

【Remmarguts' Date】的更多相关文章

  1. 【js Date】时间字符串、时间戳转换成今天,明天,本月等文字日期

    作为前端开发攻城师,难免对时间进行各种计算和格式转换,一个js的Date对象统统可以搞定.下例是将一个具体的时间转换成今天.明天.几天之内.本月等文字描述的日期的工具函数,也可以基于它扩展,多应用于网 ...

  2. 【system.date】使用说明

    对象:system.date 说明:提供一系列针对日期类型的操作 目录: 方法 返回 说明  system.date.isDate( date_string )  [True | False]  判断 ...

  3. HttpTool.java 【暂保留】

    备注 在 java tool util 工具类 中已存在 HttpTool.java 该类为java源生态的http 请求工具,不依赖第三方jar包 ,即插即用. package kingtool; ...

  4. 【废弃中】JavaScript 内置Object

    创建: 2017/09/24 更新: 2018/01/22 增加window对象内容的链接 更改标题: [JavaScript 主要的自带Object] -> [JavaScript 内置Obj ...

  5. 【POJ】【2449】Remmarguts' Date

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

  6. poj2449 Remmarguts' Date【A*算法】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4303855.html   ---by 墨染之樱花 [题目链接]:http://poj.org/ ...

  7. poj 2449 Remmarguts&#39; Date 【SPFA+Astar】【古典】

    称号:poj 2449 Remmarguts' Date 意甲冠军:给定一个图,乞讨k短路. 算法:SPFA求最短路 + AStar 以下引用大牛的分析: 首先,为了说话方便,列出一些术语: 在启示式 ...

  8. 【POJ 2449】 Remmarguts' Date

    [题目链接] http://poj.org/problem?id=2449 [算法] A*(启发式搜索) 首先,求第k短路可以用优先队列BFS实现,当T第k次入队时,就求得了第k短路,但是,这种做法的 ...

  9. 【js实例】Array类型的9个数组方法,Date类型的41个日期方法,Function类型

    前文提要:[js实例]js中的5种基本数据类型和9种操作符 Array类型的9个数组方法 Array中有9个数组方法: 1.检测数组 2.转换方法 3.栈方法 4.队列方法 5.冲排序方法6.操作方法 ...

随机推荐

  1. Welcome to Django!

    Welcome to Django! 实验简介 Django是一个可以使Web开发工作更加高效愉快的Web开发框架.Django可以让你用最小的代价构建和维护更高质量的Web应用程序. 从好的方面来看 ...

  2. Flask 蓝图(Blueprint)

    蓝图使用起来就像应用当中的子应用一样,可以有自己的模板,静态目录,有自己的视图函数和URL规则,蓝图之间互相不影响.但是它们又属于应用中,可以共享应用的配置.对于大型应用来说,我们可以通过添加蓝图来扩 ...

  3. 201621123027 Week02-Java基本语法与类库

    Week02-Java基本语法与类库 1.本周学习总结 关键词:基本语法,数据类型,包装类 本周讲了Java的基本数据类型和包装类: 数据类型主要分为八类(byte,short,int,long,do ...

  4. 解决vue2.0路由 TypeError: Cannot read property 'matched' of undefined 的错误问题

    刚开始使用vue-router2.0,虽然也用了vux,用起来却发现一个问题--具体如下: 正常情况下使用脚手架跑完之后,然后修改源项目,首先在main.js入口里把该import进去的vuex,vu ...

  5. JAVA_SE基础——9.基本数据类型间的转换

    前面我已经教会大家基本的数据类型进行了介绍,   然后这篇文章,我来介绍下,基本数据类型的转换. Java中有两种类型转换形式,分别是自动类型转换和强制类型转换. Step1.自动类型转换. 自动类型 ...

  6. 微信开发之SVN提交代码与FTP同步到apache的根目录

    SVN是协同开发的,版本控制器,就是几个人同时开发,可以提交代码到SVN服务器,这样就可以协同开发,一般是早上上班首先更新下代码,然后自己修改代码 工作一天之后,修改代码之后,下班之前,更新代码,然后 ...

  7. Ubuntu 17.10.1安装, 定制

    p { margin-bottom: 0.25cm; line-height: 120% } a:link { } 2018.4.7 Ubuntu 17.10.1安装, 定制, 后续搭建LAMP环境 ...

  8. 帧动画的创建方式 - xml方式

    废话不多说,先看东西   创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画:   本文内容主要关注 xml文件 创建帧动画的方式   xml文件 ...

  9. dubbo debug过程中一个有趣的问题

    最近在debug dubbo代码过程中遇到的很有趣的问题 我们都知道dubbo ReferenceBean是消费者的spring bean包装,为了查一个consumer端的问题,在Reference ...

  10. kubernetes入门(07)kubernetes的核心概念(4)

    一.pod 二.Volume volume可以为容器提供持久化存储,比如 三.私有镜像 在使用私有镜像时,需要创建一个docker registry secret,并在容器中引用.创建docker r ...