循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain
循环队列基础知识
1.循环队列需要几个参数来确定
循环队列需要2个参数,front和rear
2.循环队列各个参数的含义
(1)队列初始化时,front和rear值都为零;
(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置;
(3)当队列为空时,front与rear的值相等,但不一定为零;
3.循环队列入队的伪算法
(1)把值存在rear所在的位置;
(2)rear=(rear+1)%maxsize ,其中maxsize代表数组的长度;
4.循环队列出队的伪算法
(1)先保存出队的值;
(2)front=(front+1)%maxsize ,其中maxsize代表数组的长度;
5.如何判断循环队列是否为空
if(front==rear)
队列空;
else
队列不空;
6.如何判断循环队列是否为满?
这个问题比较复杂,假设数组的存数空间为7,此时已经存放1,a,5,7,22,90六个元素了,如果在往数组中添加一个元素,则rear=front;此时,队列满与队列空的判断条件front=rear相同,这样的话我们就不能判断队列到底是空还是满了;
解决这个问题有两个办法:一是增加一个参数,用来记录数组中当前元素的个数;第二个办法是,少用一个存储空间,也就是数组的最后一个存数空间不用,当(rear+1)%maxsiz=front时,队列满;

例题:
4152: [AMPPZ2014]The Captain
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 664 Solved: 256
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
2 2
1 1
4 5
7 1
6 7
Sample Output
首先,我们可以无视min,直接两点之间建一条|x2-x1|的边和一条|y2-y1|的边
可以发现,对于点(x1,y1),(x2,y2),(x3,y3),x1<x2<x3,则|x2-x1|+|x3-x2| = |x3-x1|
所以从x1连向x3用x坐标计算权值的边是没有用的。
Y同理
所以每个点只需要向上下左右最靠近的点连边,排序即可
先按x排序, 然后只有相邻节点的边才有用, 我们连起来, 再按y排序做相同操作...然后就跑dijikstra,这个题目是卡spfa的。
而且dijistra不用队优化会超时的。呵呵~。
#include<cstring>
#define N 200010
#define inf (unsigned long long)((1<<63)-1)/*直接复制(1<<63)-1是会出现-1的,在前面要有ull*/
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<algorithm>
struct Edge{
int v,last;
unsigned long long w;
}edge[N<<];
struct Jg{
int x,y;
}dian[N];
int head[N],X[N],Y[N],n,t=;
unsigned long long dis[N];
struct Dis{
int id;
unsigned long long d;
Dis(){d=inf;}
bool operator <(Dis K)
const{return d>K.d; }/*优先队列是默认大的元素在前,这个重载运算符只能对<,把他变成>即可*/
};
priority_queue<Dis>Q;
bool vis[N]={false};
inline int read()
{
int ret=,ff=;
char s=getchar();
while(s<''||s>'')
{
if(s=='-') ff=-;
s=getchar();
}
while(s>=''&&s<='')
{
ret=ret*+s-'';
s=getchar();
}
return ret*ff;
}
void input()
{
n=read();
for(int i=;i<=n;++i)
{
dian[i].x=read();dian[i].y=read();
X[i]=Y[i]=i;
}
}
bool cmpx(int a,int b)/*排序,a,b代表X[N]数组中的某两个元素,他们代表的是dian数组的编号*/
{
return dian[a].x<dian[b].x;
}
bool cmpy(int a,int b)
{
return dian[a].y<dian[b].y;
}
void add_edge(int a,int b,int falgg)
{
if(falgg==)
{
++t;
edge[t].v=b;
edge[t].w=abs(dian[a].x-dian[b].x);
edge[t].last=head[a];
head[a]=t;
}
else
{
++t;
edge[t].v=b;
edge[t].w=abs(dian[a].y-dian[b].y);
edge[t].last=head[a];
head[a]=t;
}
}
void build_line()
{/*先按x排序, 然后只有相邻节点的边才有用, 我们连起来, 再按y排序做相同操作.*/
sort(X+,X+n+,cmpx);
for(int i=;i<=n;++i)
{
add_edge(X[i],X[i-],);
add_edge(X[i-],X[i],);
}
sort(Y+,Y+n+,cmpy);
for(int i=;i<=n;++i)
{
add_edge(Y[i],Y[i-],);
add_edge(Y[i-],Y[i],);
}
}
void dijkstra()
{
for(int i=;i<=n;++i)
dis[i]=inf;
dis[]=;
Dis now;
now.id=;now.d=;
Q.push(now);
while(!Q.empty())
{
Dis nowe=Q.top();
Q.pop();
if(dis[nowe.id]!=nowe.d)continue;
if(vis[nowe.id])continue;
vis[nowe.id]=true;
for(int l=head[nowe.id];l;l=edge[l].last)
{
if(!vis[edge[l].v]&&dis[edge[l].v]>dis[nowe.id]+edge[l].w)
{
dis[edge[l].v]=dis[nowe.id]+edge[l].w;
Dis now;
now.id=edge[l].v;now.d=dis[edge[l].v];
Q.push(now);
}
}
}
}
int main()
{
input();
build_line();
dijkstra();
cout<<dis[n];
return ;
}
循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain的更多相关文章
- bzoj 4152[AMPPZ2014]The Captain
bzoj 4152[AMPPZ2014]The Captain 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. ...
- BZOJ 4152: [AMPPZ2014]The Captain( 最短路 )
先按x排序, 然后只有相邻节点的边才有用, 我们连起来, 再按y排序做相同操作...然后就dijkstra ---------------------------------------------- ...
- HDU 2544 - 最短路 - [堆优化dijkstra][最短路模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 Time Limit: 5000/1000 MS (Java/Others) Memory Li ...
- BZOJ 4152: [AMPPZ2014]The Captain Dijkstra+贪心
Code: #include <queue> #include <cstdio> #include <cstring> #include <algorithm ...
- 堆优化Dijkstra计算最短路+路径计数
今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼.然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会S ...
- BZOJ 3040 最短路 (堆优化dijkstra)
这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- 【堆优化Dijkstra+字典序最短路方案】HDU1385-Minimum Transport Cost
[题目大意] 给出邻接矩阵以及到达各个点需要付出的代价(起点和终点没有代价),求出从给定起点到终点的最短路,并输出字典序最小的方案. [思路] 在堆优化Dijkstra中,用pre记录前驱.如果新方案 ...
- PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS
PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...
随机推荐
- 找到MVC框架中前端URL与后端同步的解决方案
基本思路: 先用URL标签生成完整的URL字符,前端动态参数的部分以适配符先填充,最后动态参数利用正则匹配进行替换. 这种方式,可以在各种MVC框架中适用,妙. 不废话,上码. var url = & ...
- linux2.4.18内核定时器的使用
Linux2.4下驱动中定时器的应用 我的内核是2.4.18的.Linux的内核中定义了一个定时器的结构: #include<linux/timer.h> struct timer_lis ...
- u-boot移植总结(四)u-boot-2010.09框架分析
(一)本次移植是基于FL2440,板子的基本硬件: CPU 型号为S3C2440,基于ARM920T,指令集ARMV4,时钟主频400MHz SDRAM H57V2562GTR-75C 2片*32MB ...
- struts2进阶篇(5)
一.OGNL简介 OGNL (Object-Graph Navigation Language)的缩写,简称对象图导航语言. OGNL表达式的特特点: >能够取对象的属性,也能调用对象的方法. ...
- Linux命令详解之–ls命令
今天开始为大家介绍下Linux中常用的命令,首先给大家介绍下Linux中使用频率最高的命令--ls命令. 更多Linux命令详情请看:Linux命令速查手册 linux ls命令用于显示指定工作目录下 ...
- PHP学习笔记:伪静态规则的书写
这里以阿帕奇为服务器软件,直接上案例: 1.把index.html重定向到index.php RewriteEngine On Options -Indexes ReWriteRule ^index. ...
- Android总结篇系列:Android 权限
权限是一种安全机制.Android权限主要用于限制应用程序内部某些具有限制性特性的功能使用以及应用程序之间的组件访问.在Android开发中,基本上都会遇到联网的需求,我们知道都需要加上联网所需要的权 ...
- SQL索引学习-聚集索引
这篇接着我们的索引学习系列,这次主要来分享一些有关聚集索引的问题.上一篇SQL索引学习-索引结构主要是从一些基础概念上给大家分享了我的理解,没有实例,有朋友就提到了聚集索引的问题,这里列出来一下: 其 ...
- Linux初学者指南
1.为啥我们要学习Linux? 我们干嘛要学习Linux? Linux能给我们带来什么价值呢? Linux给我的感觉就是稳定,免费,性能好. 稳定,体现在哪里?我们使用PC机,安装的操作系统一般是wi ...
- 如何给span设置高度宽度?
内容提要:给Span设置高度和宽度后没有作用.本文介绍了如何如何给span设置高度宽度. CSS模型中经常用的容器是DIV和span. 给Span设置高度和宽度后没有作用. <style typ ...