[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 Input

5

2 2

1 1

4 5

7 1

6 7

Sample Output

2

自然是想到最短路,但一看数据范围,妈呀,吓傻了。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)的更多相关文章

  1. $bzoj4152\ The\ Captain$ 最短路

    正解:最短路+优化连边 解题报告: 传送门$w$ 这种优化连边啥的真的好妙噢$QwQ$ 首先显然离散化下不说$QwQ$.然后对所有横坐标纵坐标分别建点,相邻两横坐标点相连,边权为离散前的坐标差.纵坐标 ...

  2. 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 ...

  3. [BZOJ1579] [Usaco2009 Feb]Revamping Trails 道路升级(分层图最短路 + 堆优化dijk)

    传送门 dis[i][j]表示第i个点,更新了j次的最短路 此题不良心,卡spfa #include <queue> #include <cstdio> #include &l ...

  4. 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 ...

  5. 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 ...

  6. HDU 2544 - 最短路 - [堆优化dijkstra][最短路模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 Time Limit: 5000/1000 MS (Java/Others) Memory Li ...

  7. 【bzoj4152】[AMPPZ2014]The Captain 堆优化Dijkstra

    题目描述 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 输入 第一行包含一个正整数n(2<=n< ...

  8. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  9. Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

    2834: 回家的路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 62  Solved: 38[Submit][Status][Discuss] D ...

随机推荐

  1. Python全栈工程师(每周总结:3)

     ParisGabriel                                                           每天坚持 一天一篇 点个订阅吧  灰常感谢    当个死 ...

  2. ssh.sh_for_ubuntu1404

    #!/bin/bash sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/g' /etc/ssh/sshd_config s ...

  3. 史林枫:开源HtmlAgilityPack公共小类库封装 - 网页采集(爬虫)辅助解析利器【附源码+可视化工具推荐】

    做开发的,可能都做过信息采集相关的程序,史林枫也经常做一些数据采集或某些网站的业务办理自动化操作软件. 获取目标网页的信息很简单,使用网络编程,利用HttpWebResponse.HttpWebReq ...

  4. nginx限速白名单配置

    在<nginx限制连接数ngx_http_limit_conn_module模块>和<nginx限制请求数ngx_http_limit_req_module模块>中会对所有的I ...

  5. PHP可变变量的简单使用

    知识点: 可变变量:简单说就是将一个变量的值用作另外一个变量的命名上,例如$a = 'b';$$a就是$b HTML代码: <!doctype html> <html> < ...

  6. html & email template

    html & email template inline style build tools https://templates.mailchimp.com/getting-started/h ...

  7. 国际语言代码 Language Code

    语言代码 语言名称 af 南非语 af-ZA 南非语 ar 阿拉伯语 ar-AE 阿拉伯语(阿联酋) ar-BH 阿拉伯语(巴林) ar-DZ 阿拉伯语(阿尔及利亚) ar-EG 阿拉伯语(埃及) a ...

  8. 【bzoj4894】天赋 矩阵树定理

    题目描述 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的.也就是说,有一些天赋必须是要在学习了另一个天赋 ...

  9. [BZOJ4205][FJ2015集训] 卡牌配对 [建图+最大流]

    题面 这是bzoj权限题,题面可以去下面的离线题库找 离线4205,只有题面,不能提交 思路 二分图匹配 这道题模型显然就是个二分图匹配嘛 那我们两两判断一下然后连边匹配.....就只有30分了 因为 ...

  10. 雅礼集训 Day2 T3 联盟 解题报告

    联盟 题目描述 \(\text{G}\) 国周边的 \(n\) 个小国家构成一个联盟以抵御 \(\text{G}\) 国入侵, 为互相支援,他们建立了\(n−1\) 条双向通路, 使得任意两个国家可以 ...