zoukankan      html  css  js  c++  java
  • 【洛谷P1429】平面最近点对

    题解:直接在输入点对的基础上建立 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
    ",sqrt(ans));
    	return 0;
    } 
    
  • 相关阅读:
    3373=数据结构实验之查找一:二叉排序树
    3345=数据结构实验之二叉树六:哈夫曼编码
    3341=数据结构实验之二叉树二:遍历二叉树
    3340=数据结构实验之二叉树一:树的同构
    3362=数据结构实验之图论六:村村通公路
    Object处理方法返回值
    ASPCTJ
    myBatis 多对多
    初识MyBatis
    测试题
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10550619.html
Copyright © 2011-2022 走看看