【知识点】平面最近点对——分治

一直想学怎么求平面最近点对,看了一上午oi wiki整明白了

传送门 https://oi-wiki.org/geometry/nearest-points/

大致思路

  1.开始分治前将所有点按x坐标排序

  2.分治(l,r),如果r-l<=5,那么直接暴力求出结果然后返回

  3.反之分治左右区间,设左右子区间求出的答案为ans,

   合并时取出(l,r)的中点mid, 把所有x坐标在[xmid-ans,xmid+ans]范围的点加入集合B

   将集合B中点按照y坐标排序

   按y坐标从小到大枚举B中点i,找出B中所有y坐标在[yi,yi+ans]范围内的点j,用点i,点j更新答案(想想这么暴力为什么不会超过O(nlogn)复杂度?)

db closepoint(vector<point>&A,int l,int r){ // 最近点对 , 先要按照 x 坐标排序 
    if (r-l<=5){
        db ans=1e20;
        for (int i=l;i<=r;i++) for (int j=i+1;j<=r;j++) ans=min(ans,A[i].dis(A[j]));
        return ans;
    }
    int mid=l+r>>1; db ans=min(closepoint(A,l,mid),closepoint(A,mid+1,r));
    vector<point>B; for (int i=l;i<=r;i++) if (abs(A[i].x-A[mid].x)<=ans) B.push_back(A[i]);
    sort(B.begin(),B.end(),[](point k1,point k2){return k1.y<k2.y;});
    for (int i=0;i<B.size();i++) for (int j=i+1;j<B.size()&&B[j].y-B[i].y<ans;j++) ans=min(ans,B[i].dis(B[j]));
    return ans;
}
原文地址:https://www.cnblogs.com/zsben991126/p/13054009.html