【bzoj4152】【The Captain】最短路(堆优化)(浅尝ACM-B)
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62834538
Description
给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
Input第一行包含一个正整数n(2<=n<=200000),表示点数。
接下来n行,每行包含两个整数x[i],yi,依次表示每个点的坐标。
Output一个整数,即最小费用。
Sample Input5
2 2
1 1
4 5
7 1
6 7
Sample Output2
自然是想到最短路,但一看数据范围,妈呀,吓傻了。dijkstra?o(n*n)的复杂度(当时还不知道有堆优化这东西),肯定TLE。用spfa,竟然也TLE了!?
首先是如何建边的问题,如果把所有的点都建边就太大了,空间都爆了。仔细看题,再画图一思考,即发现只需把x轴、y轴上相邻的的点连起来(明显比其他点优)。由此一来,每个点做多就连4条边。
然后就是算法的优化了。这道题卡spfa,明显摆明了要你用优化。dijktra或spfa都可以用堆优化,手打太麻烦,可以用STL里的优先队列(才学到,长知识了)。dijktra打丑了,一直wa,无可奈何只有改打spfa,结果一遍ac,spfa大法好!
坑点还是蛮多的,放在代码里面了
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define ll long long
using namespace std;
const int N=200000+5;
int n;
int head[N],end[4*N],nxt[4*N],dis[4*N],hh=0;
struct Node{
int num,x,y;
}a[N];
ll dist[N];bool vis[N],con[N];
void adde(int a,int b,int di){
hh++;
end[hh]=b;
dis[hh]=di;
nxt[hh]=head[a];
head[a]=hh;
}
/*struct cmp{
bool operator()(int a,int b){
return dist[a]>dist[b];
}
};*/
bool cmp1(Node a,Node b){
return a.x<b.x;
}
bool cmp2(Node a,Node b){
return a.y<b.y;
}
int abs(int a){
return a<0?-a:a;
}
/*写wa了的dijkstra
ll dijkstra(int st,int en){
priority_queue<int,vector<int>,cmp> q;
memset(dist,0x3f,sizeof(dist));
dist[st]=0;
vis[st]=1;
con[st]=1;
q.push(st);
while(!q.empty()){
int u=q.top();q.pop();
con[u]=1;
if(u==en) break;
for(int i=head[u];i;i=nxt[i]){
int v=end[i],di=dis[i];//printf("%d ",v);
if(con[v]==1) continue;
if(dist[u]+(ll)di<dist[v]){
dist[v]=dist[u]+(ll)di;
if(!vis[v]){
q.push(v);
vis[v]=1;
}
}
}
}
return dist[en];
}*/
ll spfa(int st,int en){
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;//优先队列(堆)
q.push(make_pair(0,st));
vis[st]=1;
dist[st]=0;
while(!q.empty()){
int u=q.top().second;
q.pop();//q是优先队列,后pop可能就不是u了
vis[u]=0;//还可能会被更新
for(int i=head[u];i;i=nxt[i]){
int v=end[i],di=dis[i];
if(dist[v]>dist[u]+di){
dist[v]=dist[u]+di;
if(!vis[v]){
q.push(make_pair(dist[v],v));
vis[v]=1;
}
}
}
}
return dist[en];
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
a[i].num=i;
}
sort(a+1,a+n+1,cmp1);
for(int i=1;i<=n;i++){
if(i>1) adde(a[i].num,a[i-1].num,min(a[i].x-a[i-1].x,abs(a[i].y-a[i-1].y)));//建边要注意了,x轴上相邻的点可能y轴上的距离更近
if(i<n) adde(a[i].num,a[i+1].num,min(a[i+1].x-a[i].x,abs(a[i].y-a[i+1].y)));
}
sort(a+1,a+n+1,cmp2);
for(int i=1;i<=n;i++){
if(i>1) adde(a[i].num,a[i-1].num,min(a[i].y-a[i-1].y,abs(a[i].x-a[i-1].x)));
if(i<n) adde(a[i].num,a[i+1].num,min(a[i+1].y-a[i].y,abs(a[i].x-a[i+1].x)));
}
printf("%lld",/*dijkstra(1,n)*/spfa(1,n));
return 0;
}
【bzoj4152】【The Captain】最短路(堆优化)(浅尝ACM-B)的更多相关文章
- $bzoj4152\ The\ Captain$ 最短路
正解:最短路+优化连边 解题报告: 传送门$w$ 这种优化连边啥的真的好妙噢$QwQ$ 首先显然离散化下不说$QwQ$.然后对所有横坐标纵坐标分别建点,相邻两横坐标点相连,边权为离散前的坐标差.纵坐标 ...
- CCPC-Wannafly Winter Camp Day1 Div1 - 爬爬爬山 - [最短路][堆优化dijkstra]
题目链接:https://zhixincode.com/contest/3/problem/F?problem_id=39 样例输入 1 4 5 1 1 2 3 4 1 2 1 1 3 1 1 4 ...
- [BZOJ1579] [Usaco2009 Feb]Revamping Trails 道路升级(分层图最短路 + 堆优化dijk)
传送门 dis[i][j]表示第i个点,更新了j次的最短路 此题不良心,卡spfa #include <queue> #include <cstdio> #include &l ...
- LibreOJ #119. 最短路 (堆优化dijkstra)
题目描述 给一个 n(1≤2500≤n) n(1 \leq 2500 \leq n)n(1≤2500≤n) 个点 m(1≤6200≤m) m(1 \leq 6200 \leq m)m(1≤6200≤m ...
- Codeforces Round #287 (Div. 2) E. Breaking Good 路径记录!!!+最短路+堆优化
E. Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- HDU 2544 - 最短路 - [堆优化dijkstra][最短路模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 Time Limit: 5000/1000 MS (Java/Others) Memory Li ...
- 【bzoj4152】[AMPPZ2014]The Captain 堆优化Dijkstra
题目描述 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 输入 第一行包含一个正整数n(2<=n< ...
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...
- Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路
2834: 回家的路 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 62 Solved: 38[Submit][Status][Discuss] D ...
随机推荐
- 源码分析(一) HashMap 源码分析|JDK8
HashMap是一个普遍应用于各大JAVA平台的最最最常用的数据结构.<K,V>的存储形式使HashMap备受广大java程序员的喜欢.JDK8中HashMap发生了很大的变化,例如:之前 ...
- 1043 Is It a Binary Search Tree (25 分)(二叉查找树)
#include<bits/stdc++.h> using namespace std; typedef struct node; typedef node *tree; struct n ...
- mongodb 部署
安装mongodb-3.4 1)将安装包上传至服务器 2)对压缩文件进行解压 tar -zxvf mongodb-linux-x86_64-suse12-v3.4-latest.tar.gz 3)把解 ...
- kubeadm部署k8s1.9高可用集群--4部署master节点
部署master节点 kubernetes master 节点包含的组件: kube-apiserver kube-scheduler kube-controller-manager 本文档介绍部署一 ...
- SpringBoot Rabbitmq发送消息
官方文档:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-amqp ...
- Java 循环队列的实现
队列概念 队列(Queue)是限定只能在一端插入.另一端删除的线性表.允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear),没有元素的队列称为“空队列”. 队列具有先进先出(FIF ...
- 【Python】- pytharm 中import时无法识别自己写的程序
右键点击自己的工作空间,找下面的Mark Directory as(将目录标记为) 选择Source Root,就可以解决上面的问题了,如图
- Spark on Yarn——spark1.5.1集群配置
写在前面: spark只是一种计算框架,如果要搭建集群要依托与一定的组织模式. 目前来说,Spark集群的组织形式有三种: 1. Standalone:使用akka作为网络IO组件,mast ...
- 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)
已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...
- 狂K 线段树
想写好树剖~~线段树very important HDU 1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536 ...