【Remmarguts' Date】
一道来自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】的更多相关文章
- 【js Date】时间字符串、时间戳转换成今天,明天,本月等文字日期
作为前端开发攻城师,难免对时间进行各种计算和格式转换,一个js的Date对象统统可以搞定.下例是将一个具体的时间转换成今天.明天.几天之内.本月等文字描述的日期的工具函数,也可以基于它扩展,多应用于网 ...
- 【system.date】使用说明
对象:system.date 说明:提供一系列针对日期类型的操作 目录: 方法 返回 说明 system.date.isDate( date_string ) [True | False] 判断 ...
- HttpTool.java 【暂保留】
备注 在 java tool util 工具类 中已存在 HttpTool.java 该类为java源生态的http 请求工具,不依赖第三方jar包 ,即插即用. package kingtool; ...
- 【废弃中】JavaScript 内置Object
创建: 2017/09/24 更新: 2018/01/22 增加window对象内容的链接 更改标题: [JavaScript 主要的自带Object] -> [JavaScript 内置Obj ...
- 【POJ】【2449】Remmarguts' Date
K短路/A* 经(luo)典(ti) K短路题目= = K短路学习:http://www.cnblogs.com/Hilda/p/3226692.html 流程: 先把所有边逆向,做一遍dijkstr ...
- poj2449 Remmarguts' Date【A*算法】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4303855.html ---by 墨染之樱花 [题目链接]:http://poj.org/ ...
- poj 2449 Remmarguts' Date 【SPFA+Astar】【古典】
称号:poj 2449 Remmarguts' Date 意甲冠军:给定一个图,乞讨k短路. 算法:SPFA求最短路 + AStar 以下引用大牛的分析: 首先,为了说话方便,列出一些术语: 在启示式 ...
- 【POJ 2449】 Remmarguts' Date
[题目链接] http://poj.org/problem?id=2449 [算法] A*(启发式搜索) 首先,求第k短路可以用优先队列BFS实现,当T第k次入队时,就求得了第k短路,但是,这种做法的 ...
- 【js实例】Array类型的9个数组方法,Date类型的41个日期方法,Function类型
前文提要:[js实例]js中的5种基本数据类型和9种操作符 Array类型的9个数组方法 Array中有9个数组方法: 1.检测数组 2.转换方法 3.栈方法 4.队列方法 5.冲排序方法6.操作方法 ...
随机推荐
- 团队作业4——第一次项目冲刺(Alpha版本)2017.11.14
第一次会议:2017-11-14 额--这几天比较忙,忘记上传了,今天补上 先上个图,O(∩_∩)O哈哈: 会议主要内容: 1. 讨论整体框架 2. 个人具体分工 3. 代码统一 具体分工: 成员 计 ...
- MariaDB/MySQL存储过程和函数
本文目录:1.创建存储过程.函数 1.1 存储过程的IN.OUT和INOUT2.修改和删除存储过程.函数3.查看存储过程.函数信息 在MySQL/MariaDB中,存储过程(stored proced ...
- Ubuntu的软件管理与安装
感谢燕十八,的Linux的基础进阶视频 来哥:应该是装的wineQQ,它用的12年的国际版,ubuntu的这个版本应该比较好用! [3]apt-get 用Linux apt-get命令的第一步就是引入 ...
- JQ 标签相关知识
1.判断 checkbox 和 radio 是否选中 if($("标签选择器").is(":checked")) 2.改变 checkbox 选中状态 .pro ...
- JsonCPP库使用
1.使用环境DevC++ a.建立C++工程,并添加.\JsonCPP\jsoncpp-master\jsoncpp-master\src\lib_json中源文件到工程中. b.添加头文件路径 2. ...
- 百度资深架构师带你深入浅出一致性Hash原理
一.前言 在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡的作用. 但是普通的余数h ...
- Android:触屏事件
Android触屏事件包含两种: 1)屏幕触屏事件:重写onTouchEvent(MotionEvent event): 2)控件触屏事件:给控件注册触屏事件,setOnTouchEventListe ...
- requests-所有异常归类
IOError RequestException HTTPError(RequestException) UnrewindableBodyError(RequestException) RetryEr ...
- PHP 通过fsockopen函数获取远程网页源码
<?php $fp = fsockopen("www.baidu.com", 80, &$errno, &$errstr, 10); if(!$fp) { e ...
- CentOS 7 安装Boost 1.61
1. 到官网下载最新版的boost,http://www.boost.org/users/history/version_1_61_0.html 2. 解压: tar zxvf boost_1_61_ ...