题解:直接在输入点对的基础上建立 kd-tree,再每次以每个节点的坐标查询离这个点最近的点即可,同时需要忽略这个点本身对该点答案的贡献。

另外,直接在这些点上建立 kd-tree 会比一个一个插入点建立的更平衡,直接插入由于缺少了 nth_element 的划分,导致树很容易退化。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
inline double sqr(double val){return val*val;} struct node{
#define ls(x) t[x].lc
#define rs(x) t[x].rc
int lc,rc;
double p[2],x[2],y[2];
}t[maxn];
int root,d;double ans;
inline bool cmp(const node &x,const node &y){return x.p[d]<y.p[d];}
inline double getdis(int o,double x,double y){
return sqr(max((double)0,max(t[o].x[0]-x,x-t[o].x[1])))+sqr(max((double)0,max(t[o].y[0]-y,y-t[o].y[1])));
}
inline void pushup(int o){
t[o].x[0]=min(t[o].p[0],min(t[ls(o)].x[0],t[rs(o)].x[0]));
t[o].x[1]=max(t[o].p[0],max(t[ls(o)].x[1],t[rs(o)].x[1]));
t[o].y[0]=min(t[o].p[1],min(t[ls(o)].y[0],t[rs(o)].y[0]));
t[o].y[1]=max(t[o].p[1],max(t[ls(o)].y[1],t[rs(o)].y[1]));
}
int build(int l,int r,int now){
if(l>r)return 0;
int mid=l+r>>1;
d=now,nth_element(t+l,t+mid,t+r+1,cmp);
ls(mid)=build(l,mid-1,now^1),rs(mid)=build(mid+1,r,now^1);
return pushup(mid),mid;
}
void query(int o,double x,double y,int idx){
double dn=sqr(x-t[o].p[0])+sqr(y-t[o].p[1]),dl,dr;
if(o!=idx)ans=min(ans,dn);
dl=ls(o)?getdis(ls(o),x,y):4e18;
dr=rs(o)?getdis(rs(o),x,y):4e18;
if(dl<dr){
if(dl<ans)query(ls(o),x,y,idx);
if(dr<ans)query(rs(o),x,y,idx);
}else{
if(dr<ans)query(rs(o),x,y,idx);
if(dl<ans)query(ls(o),x,y,idx);
}
}
void init(){ans=4e18,t[0].x[0]=t[0].y[0]=4e18,t[0].x[1]=t[0].y[1]=-4e18;} int n;double p[2];
int main(){
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lf%lfd",&t[i].p[0],&t[i].p[1]);
root=build(1,n,0);
for(int i=1;i<=n;i++)query(root,t[i].p[0],t[i].p[1],i);
printf("%.4lf\n",sqrt(ans));
return 0;
}

【洛谷P1429】平面最近点对的更多相关文章

  1. (洛谷 P1429 平面最近点对(加强版) || 洛谷 P1257 || Quoit Design HDU - 1007 ) && Raid POJ - 3714

    这个讲的好: https://phoenixzhao.github.io/%E6%B1%82%E6%9C%80%E8%BF%91%E5%AF%B9%E7%9A%84%E4%B8%89%E7%A7%8D ...

  2. 洛谷 P1429 平面最近点对(加强版) (分治模板题)

    题意:有\(n\)个点对,找到它们之间的最短距离. 题解:我们先对所有点对以\(x\)的大小进行排序,然后分治,每次左右二等分递归下去,当\(l+1=r\)的时候,我们计算一下距离直接返回给上一层,若 ...

  3. 洛谷1429 平面最近点对(KDTree)

    qwq(明明可以直接分治过掉的) 但是还是当作联系了 首先,对于这种点的题,很显然的套路,我们要维护一个子树\(mx[i],mn[i]\)分别表示每个维度的最大值和最小值 (这里有一个要注意的东西!就 ...

  4. Luogu P1429 平面最近点对(加强版)(分治)

    P1429 平面最近点对(加强版) 题意 题目描述 给定平面上\(n\)个点,找出其中的一对点的距离,使得在这\(n\)个点的所有点对中,该距离为所有点对中最小的. 输入输出格式 输入格式: 第一行: ...

  5. P1429 平面最近点对(加强版)(分治)

    P1429 平面最近点对(加强版) 主要思路: 分治,将点按横坐标为第1关键字升序排列,纵坐标为第2关键字升序排列,进入左半边和右半边进行分治. 设d为左右半边的最小点对值.然后以mid这个点为中心, ...

  6. P1429 平面最近点对[加强版] 随机化

    LINK:平面最近点对 加强版 有一种分治的做法 因为按照x排序分治再按y排序 可以证明每次一个只会和周边的六个点进行更新. 好像不算很难 这里给出一种随机化的做法. 前置知识是旋转坐标系 即以某个点 ...

  7. 洛谷P1257 平面上的最接近点对

    n<=10000个点,求欧几里德距离最小的一对点. 经典分治,把这些点按x排序,分成两半,每边分别算答案,答案是左边的最小,右边的最小,左右组起来的最小三者的最小.发现只有左右组的有点难写. 假 ...

  8. p1429 平面最近点对(加强版)

    传送门 分析 我们可以枚举每一个点算它的最近点 估价函数应该分为3种情况计算: 大于max,小于min,位于min和max之间 代码 #include<iostream> #include ...

  9. Luogu P1429 平面最近点对 【分治】By cellur925

    题目传送门 题目大意:给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的.$n$<=100000. $Algorithm$ 最朴素的$n^2$枚举肯定 ...

随机推荐

  1. 【下一代核心技术DevOps】:(三)私有代码库阿里云Git使用

    1. 引言 使用DevOps肯定离不开和代码的集成.所以要想跑通整套流程,代码库的选型也是非常重要的.否则无法实现持续集成.目前比较常用的代码管理有SVN和GIt 如果还使用SVN的,建议尽早迁移到G ...

  2. Ext JS 4 的类系统

    前言 我们知道,JavaScript中没有真正的类,它是一种面向原型的语言 .这种语言一个强大的特性就是灵活,实现一个功能可以有很多不同的方式,用不同的编码风格和技巧.但随之也带来了代码的不可预测和难 ...

  3. ACM注意事项

           acm竞赛中不能使用一些屏幕控制和键盘读取的函数,如:getch(),geche(),gotoxy(),clrscr(),另外fflush(stdio)这个函数也不能使用,因为在有的编译 ...

  4. OneZero第一次随感

    >本人基础薄弱,有幸加入这个团队,甚感欣慰.这是本人第一次尝试写博客,说实话,胆怯.因为能力有限,怕技能匮乏,说不好.但是我知道既然加入这个团队,就要为团队负责.万事开头难,过程也挺难(就我个人 ...

  5. 四则运算法则在Java中的实现

    软件工程的课程已经上过有一段时间了,前段时间由于比较忙着考试,所以关于四则运算的代码一直没有实现.同时由于近来一段时间一直在自学java,因为C++虽然也是面向对象,而且可以开发很多软件或者程序,但是 ...

  6. Prism6下的MEF:基于微软企业库的Cache

    通常,应用程序可以将那些频繁访问的数据,以及那些需要大量处理时间来创建的数据存储在内存中,从而提高性能.基于微软的企业库,我们的快速创建一个缓存的实现. 新建PrismSample.Infrastru ...

  7. beta版验收互评

    排名 团队名称 项目名称 优点 缺点,bug 报告 1 别看了你没救了队 校园帮帮帮(已发布) 实现普通用户的登陆,修改个人信息,发布信息,下订单的功能:管理员登陆,修改个人信息,发布信息,下订单,增 ...

  8. spring 整合

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. Kitematic - VirtualBox is not installed. Docker for windows 10

    Kitematic - VirtualBox is not installed. Docker for windows 10 https://github.com/docker/kitematic/i ...

  10. Java微信二次开发(六)

    Token定时获取 需要导入库:添加log4j(slf4j-api-1.5.10.jar,slf4j-log4j12-1.5.10.jar,log4j-1.2.15.jar,并且在src下添加log4 ...