『The Captain 最短路建图优化』
<更新提示>
<第一次更新>
<正文>
The Captain(BZOJ 4152)
Description
给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
Input Format
第一行包含一个正整数n(2<=n<=200000),表示点数。
接下来n行,每行包含两个整数xi,yi(0<=xi,yi<=10^9),依次表示每个点的坐标。
Output Format
一个整数,即最小费用。
Sample Input
5
2 2
1 1
4 5
7 1
6 7
Sample Output
2
解析
假如说我们直接将平面中的每一个点视为图中的每一个点的话,这就是一道最短路问题。但是显而易见的是我们需要连\(n^2\)条边,这是一定会超时的,主要考虑如何建图优化。
手推几个样例可以发现图中有很多无用的边存在,我们考虑证明什么情况下的连边是不必要的。
证明:
对于任意两点\(P,Q\),其距离为\(\min\{\Delta x,\Delta y\}\).
- 距离取\(\Delta x\):
假如在横坐标意义上\(P,Q\)有中间点\(M\).
- \(PM\)取\(\Delta x_{pm}\),\(MQ\)取\(\Delta x_{mq}\),则\(PQ\)连边和\(PM\),\(MQ\)等价.
- \(PM\)取\(\Delta x_{pm}\),\(MQ\)取\(\Delta y_{mq}\),由于\(\Delta y_{mq}<\Delta x_{mq}\),\(PQ\)连边大于\(PM\),\(MQ\).
- \(PM\)取\(\Delta y_{pm}\),\(MQ\)取\(\Delta x_{mq}\),由于\(\Delta y_{pm}<\Delta x_{pm}\),\(PQ\)连边大于\(PM\),\(MQ\).
- \(PM\)取\(\Delta y_{pm}\),\(MQ\)取\(\Delta y_{mq}\),由于\(\Delta y_{pm}<\Delta x_{pm}\),\(\Delta y_{mq}<\Delta x_{mq}\),\(PQ\)连边大于\(PM\),\(MQ\).
所以,当\(P,Q\)距离取\(\Delta x\),且横坐标意义上\(P,Q\)有中间点\(M\)时,\(PQ\)连边一定不能对最优解造成贡献。
- 距离取\(\Delta y\):
假如在纵坐标意义上\(P,Q\)有中间点\(M\),同理\(PQ\)连边一定不能对最优解造成贡献。
得出结论:当\(P,Q\)距离取\(\Delta x\),且横坐标意义上\(P,Q\)有中间点\(M\),或者距离取\(\Delta y\),纵坐标意义上\(P,Q\)有中间点\(M\)时,\(PQ\)连边一定不能对最优解造成贡献。
那么这就是不必要连的边。相反,则任意两点\(U,V\)距离取\(\Delta x\),且横坐标意义上\(U,V\)相邻,或者\(U,V\)距离取\(\Delta y\),且纵坐标意义上\(U,V\)相邻时,\(U,V\)连边是必要的。
那么我们把必要的边连起来就行了,这样的边至多有\(2n\)条,堆优化\(Dijkstra\)解决最短路问题。
\(Code:\)
#include<bits/stdc++.h>
using namespace std;
const int N=200000+80;
struct node{int num,x,y;}p[N];
struct edge{int ver,val,next;}e[N*4];
int n,t,Last[N*4],dis[N],vis[N];
inline bool cmp1(node p1,node p2){return p1.x<p2.x;}
inline bool cmp2(node p1,node p2){return p1.y<p2.y;}
inline bool check1(node p1,node p2){return p2.x-p1.x<=abs(p1.y-p2.y);}
inline bool check2(node p1,node p2){return p2.y-p1.y<abs(p1.x-p2.x);}
inline void insert(int x,int y,int v)
{
e[++t].val=v;e[t].ver=y;
e[t].next=Last[x];Last[x]=t;
}
inline void input(void)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].num=i;
}
}
inline void init(void)
{
sort(p+1,p+n+1,cmp1);
for(int i=1;i<n;i++)
{
if(check1(p[i],p[i+1]))
insert(p[i].num,p[i+1].num,p[i+1].x-p[i].x),insert(p[i+1].num,p[i].num,p[i+1].x-p[i].x);;
}
sort(p+1,p+n+1,cmp2);
for(int i=1;i<n;i++)
{
if(check2(p[i],p[i+1]))
insert(p[i].num,p[i+1].num,p[i+1].y-p[i].y),insert(p[i+1].num,p[i].num,p[i+1].y-p[i].y);
}
}
inline void dijkstra(void)
{
memset(dis,0x3f,sizeof dis);
priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > >Heap;
dis[1]=0;Heap.push(make_pair(0,1));
while(!Heap.empty())
{
int temp=Heap.top().second;
Heap.pop();
if(vis[temp])continue;
vis[temp]=true;
for(int i=Last[temp];i;i=e[i].next)
{
if(dis[e[i].ver]>dis[temp]+e[i].val)
{
dis[e[i].ver]=dis[temp]+e[i].val;
Heap.push(make_pair(dis[e[i].ver],e[i].ver));
}
}
}
}
int main(void)
{
input();
init();
dijkstra();
printf("%d\n",dis[n]);
return 0;
}
<后记>
『The Captain 最短路建图优化』的更多相关文章
- [Code+#4] 最短路 - 建图优化,最短路
最短路问题,然而对于任意\(i,j\),从\(i\)到\(j\)可以只花费\((i xor j) \cdot C\) 对每个点\(i\),只考虑到\(j\)满足\(j=i xor 2^k, j \le ...
- BZOJ4383/LuoGuP3588 Pustynia/PUS 线段树建图优化
我会告诉你我看了很久很久才把题目看懂吗???怀疑智商了 原来他给的l,r还有k个数字都是下标... 比如给了一个样例 l, r, k, x1,x2,x3...xk,代表的是一个数组num[l]~num ...
- 『炸弹 线段树优化建图 Tarjan』
炸弹(SNOI2017) Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸 时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi ...
- HDU 5521 [图论][最短路][建图灵感]
/* 思前想后 还是决定坚持写博客吧... 题意: n个点,m个集合.每个集合里边的点是联通的且任意两点之间有一条dis[i]的边(每个集合一个dis[i]) 求同时从第1个点和第n个点出发的两个人相 ...
- hdu4725 The Shortest Path in Nya Graph【最短路+建图】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4297574.html ---by 墨染之樱花 题目链接:http://acm.hdu ...
- Codeforces 938D. Buy a Ticket (最短路+建图)
<题目链接> 题目大意: 有n座城市,每一个城市都有一个听演唱会的价格,这n座城市由m条无向边连接,每天变都有其对应的边权.现在要求出每个城市的人,看一场演唱会的最小价值(总共花费的价值= ...
- HDU5521-最短路-建图
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- hdu 5294 Tricks Device 最短路建图+最小割
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Other ...
- hdu 4725 The Shortest Path in Nya Graph (最短路+建图)
The Shortest Path in Nya Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ...
随机推荐
- Mysql之SQL经验基础积累
1.根据create_time排序,如何确保null值的排在最前面: 解决办法: ,), a.create_time DESC 结果如下图:
- vue v-for循环的用法
1.v-for循环普通数组 ①创建vue对象 ② 循环数据 结果: 2.v-for循环对象数组 ① 创建vue实例对象 ② 循环对象数组 结果: 3.v-for循环对象 ①创建vue对象实例 ②循环对 ...
- 使用JumpServer管理你的服务器
本文介绍CentOS 7从安装jumpserver到简单使用jumpserver管理服务器. 1.Jumpserver介绍 Jumpserver是一款开源的开源的堡垒机,如下图是官网介绍. 官网地址: ...
- 【转】HTML CANVAS
https://blog.csdn.net/u012468376/article/details/73350998 学习HTML5 Canvas这一篇文章就够了 2017年06月16日 20:57:4 ...
- windows server 远程桌面连接问题。
远程桌面连接相当于 linux 服务器root权限连接 mstsc /admin /v:目标IP mstsc /admin /
- 用java从0生成一个简单的excel
用java从0生成一个简单的excel 目标 用代码实现对一个excel的基础操作,包括创建,插入文字,(好像就这些了),生成的excel可以用wps打开,如果直接用c++的文件流会生成假的xls表格 ...
- Github把自己的本地项目托管到git上
开篇之前说下题外话,之前写过一篇博客,IOS-一步一步教你自定义评分星级条RatingBar,群里有人想要源码,我上传到github上了,有需要的可以去看一下,github地址自定义评分星级条 言归正 ...
- ajaj简介
1. 什么是ajax? ajax的全称 Asynchronous(异步) JavaScript and XML. ajax是一种用于创建快速动态网页的技术. 主要用于前后台的交互,在前后台的交互中还有 ...
- java代码编译与C/C++代码编译的区别
Java编译原理 1.Java编译过程与c/c++编译过程不同 Java编译程序将java源程序编译成jvm可执行代码--java字节码. Java在编译过程中一般会按照以下过程进行: (1)JDK根 ...
- Django(Python)前后端交互
使用Django中自带的模板 前端通过form 表单向后端提交数据 # /template/demo/demo.html {% if result == 1 %} <p> 插入成功 < ...