本文主要是介绍[caioj1206][kdtree]最近点对的距离,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【题意】
给出n个点的坐标,求最近两点间的距离。
【输入格式】
第一行一个整数n(2 ≤ n ≤ 50000)。 下来n行,每行两个实数x和y表示点坐标。
【输出格式】
一行一个实数,表示最近两点间的距离(保留4位小数)。
【样例输入】
5
0 0
0 5
5 0
5 5
2 0
【样例输出】
2.0000
题解
扔一个欧几里得最短距离的模板
直接上kdtree
注意如果搜到自己了,那么不继承
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
struct node
{LL mx[2],mn[2],d[2];int lc,rc;node(){lc=rc=0;}
}tr[210000];int trlen;
void update(int x)
{int lc=tr[x].lc,rc=tr[x].rc;if(lc){tr[x].mx[0]=max(tr[x].mx[0],tr[lc].mx[0]);tr[x].mn[0]=min(tr[x].mn[0],tr[lc].mn[0]);tr[x].mx[1]=max(tr[x].mx[1],tr[lc].mx[1]);tr[x].mn[1]=min(tr[x].mn[1],tr[lc].mn[1]);}if(rc){tr[x].mx[0]=max(tr[x].mx[0],tr[rc].mx[0]);tr[x].mn[0]=min(tr[x].mn[0],tr[rc].mn[0]);tr[x].mx[1]=max(tr[x].mx[1],tr[rc].mx[1]);tr[x].mn[1]=min(tr[x].mn[1],tr[rc].mn[1]);}
}
int cmpd;
bool cmp(node n1,node n2)
{return n1.d[cmpd]<n2.d[cmpd] || n1.d[cmpd]==n2.d[cmpd] && n1.d[cmpd^1]<n2.d[cmpd^1];
}
int bt(int l,int r,int d)
{int mid=(l+r)/2;int now;cmpd=d;now=mid;nth_element(tr+l,tr+mid,tr+r+1,cmp);tr[now].mx[0]=tr[now].mn[0]=tr[now].d[0];tr[now].mx[1]=tr[now].mn[1]=tr[now].d[1];if(l<mid)tr[now].lc=bt(l,mid-1,d^1);if(mid<r)tr[now].rc=bt(mid+1,r,d^1);update(now);return now;
}
LL nowx,nowy;int root,n;
LL minn;
LL sqr(LL x){return (x*x);}
LL dismin(int now,LL x,LL y)
{LL ans=0;if(x<tr[now].mn[0])ans+=sqr(tr[now].mn[0]-x);if(x>tr[now].mx[0])ans+=sqr(x-tr[now].mx[0]);if(y<tr[now].mn[1])ans+=sqr(tr[now].mn[1]-y);if(y>tr[now].mx[1])ans+=sqr(y-tr[now].mx[1]);return ans;
}
void solmin(int now)
{LL d0=((tr[now].d[0]-nowx)*(tr[now].d[0]-nowx)+(tr[now].d[1]-nowy)*(tr[now].d[1]-nowy));if(d0)minn=min(minn,d0);LL d1=4e18,d2=4e18;if(tr[now].lc)d1=dismin(tr[now].lc,nowx,nowy);if(tr[now].rc)d2=dismin(tr[now].rc,nowx,nowy);if(d1<d2){if(d1<minn)solmin(tr[now].lc);if(d2<minn)solmin(tr[now].rc);}else{if(d2<minn)solmin(tr[now].rc);if(d1<minn)solmin(tr[now].lc);}
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lld%lld",&tr[i].d[0],&tr[i].d[1]);root=bt(1,n,0);minn=4e18;for(int i=1;i<=n;i++){nowx=tr[i].d[0];nowy=tr[i].d[1];solmin(root);}printf("%.4lf\n",sqrt(double(minn)));return 0;
}
这篇关于[caioj1206][kdtree]最近点对的距离的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!