博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
『The Captain 最短路建图优化』
阅读量:7061 次
发布时间:2019-06-28

本文共 2259 字,大约阅读时间需要 7 分钟。


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\).
  1. \(PM\)\(\Delta x_{pm}\)\(MQ\)\(\Delta x_{mq}\),则\(PQ\)连边和\(PM\)\(MQ\)等价.
  2. \(PM\)\(\Delta x_{pm}\)\(MQ\)\(\Delta y_{mq}\),由于\(\Delta y_{mq}<\Delta x_{mq}\)\(PQ\)连边大于\(PM\)\(MQ\).
  3. \(PM\)\(\Delta y_{pm}\)\(MQ\)\(\Delta x_{mq}\),由于\(\Delta y_{pm}<\Delta x_{pm}\)\(PQ\)连边大于\(PM\)\(MQ\).
  4. \(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
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
,vector< pair
>,greater< pair
> >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;}


转载于:https://www.cnblogs.com/Parsnip/p/10360838.html

你可能感兴趣的文章
6-8-并查集(等价类)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版...
查看>>
Log4j 输出的日志中时间比系统时间少了8小时的解决方法,log4j日志文件重复输出...
查看>>
UML用例图总结
查看>>
[改善Java代码]优先使用整型池
查看>>
iOS中设置导航栏标题的字体颜色和大小
查看>>
h.264并行解码算法分析
查看>>
ALSA声音编程介绍
查看>>
bootstrap fileinput 文件上传工具
查看>>
C# String 前面不足位数补零的方法
查看>>
route命令
查看>>
KETTLE、spoon使用
查看>>
如何生成密钥,私钥,签名
查看>>
etc下
查看>>
iOS - Swift NSData 数据
查看>>
基础知识→设计模式
查看>>
Chrome 启动参数列表
查看>>
Django中Form的Textarea字段
查看>>
CSS3与页面布局学习总结(八)——浏览器兼容与前端性能优化
查看>>
jQuery遮罩层登录对话框
查看>>
介绍对称加密的另一个算法——PBE
查看>>