[模板]平面最近点对

实现

将平面内点按$x$坐标排序,分治$x$坐标,设$ret=min(f(l,mid),f(mid+1,r))$,

将$xin[mid-ret,mid+ret]$内的点按$y$坐标排序,算每个点与相邻的$6$个点的距离找最优解即可.

时间复杂度:$O(nlogn)$.

#define N 100005
#define INF 1e15
struct point{
    double x,y;
}p[N];
inline double sqr(double k){
    return k*k;
}
inline double dis(point x,point y){
    return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));
}
inline bool cmpx(point x,point y){
    if(x.x!=y.x) return x.x<y.x;
    return x.y<y.y;
}
inline bool cmpy(point x,point y){
    if(x.y!=y.y) return x.y<y.y;
    return x.x<y.x;
}
inline double min_d(int l,int r){
    double ret=INF;
    if(r-l<=20){
        for(int i=l;i<r;++i)
            for(int j=i+1;j<=r;++j)
                ret=min(ret,dis(p[i],p[j]));
        return ret;
    }
    int mid=l+r>>1;
    ret=min(min_d(l,mid),min_d(mid+1,r)); 
    while(p[l].x+ret<p[mid].x) ++l;
    while(p[r].x-ret>p[mid].x) --r;
    sort(p+l,p+1+r,cmpy);
    for(int i=l;i<r;++i)
        for(int j=min(r,i+6);j>i;--j)
            ret=min(ret,dis(p[i],p[j])); 
    sort(p+l,p+1+r,cmpx);
    return ret;
}
inline double min_dis(){
    sort(p+1,p+1+n,cmpx);
    return min_d(1,n);
}

推荐

http://www.cnblogs.com/xdruid/archive/2012/05/27/CP.html

原文地址:https://www.cnblogs.com/AireenYe/p/6257620.html