利用分治来求平面最近点对
只需要查后面6个点就好了
原因在于https://blog.csdn.net/liufeng_king/article/details/8484284
两个集合的话就把不同集合的设为inf就好了
1 const db inf = 1e100; 2 3 ll sqr(ll x) { return x*x; } 4 5 struct point { 6 int x,y; 7 int f; 8 void in() { 9 scanf("%d%d",&x,&y); 10 } 11 point operator-(const point &b) const { 12 point ret; 13 ret.x=x-b.x; 14 ret.y=y-b.y; 15 return ret; 16 } 17 db mean() { 18 ll ret=0; 19 ret=sqr(x)+sqr(y); 20 return sqrt(ret); 21 } 22 }; 23 24 point a[N]; 25 26 db dis(point a,point b) { 27 db ret=0; 28 if(a.f==b.f) return inf; 29 ret=(a-b).mean(); 30 return ret; 31 } 32 33 bool cmp_x(point a,point b) { 34 return a.x<b.x; 35 } 36 37 int t[N]; 38 bool cmp_t(int x,int y) { 39 return a[t[x]].y<a[t[y]].y; 40 } 41 42 db F(int l,int r) { 43 if(l==r) return inf; 44 if(l+1==r) return dis(a[r],a[l]); 45 int mid=(l+r)>>1; 46 db ans1=F(l,mid); 47 db ans2=F(mid+1,r); 48 db ans=min(ans1,ans2); 49 if(ans==0) return ans; 50 int nm=0; 51 for(int i=l;i<=r;i++) if(a[mid].x-ans<=a[i].x && a[i].x<=a[mid].x+ans) { 52 t[++nm]=i; 53 } 54 sort(t+1,t+nm+1,cmp_t); 55 for(int i=1;i<=nm;i++) { 56 for(int j=i+1;j<=min(nm,i+6);j++) { 57 db anss=dis(a[t[i]],a[t[j]]); 58 ans=min(ans,anss); 59 } 60 } 61 return ans; 62 } 63 64 int main() { 65 int T; 66 scanf("%d",&T); 67 while(T--) { 68 int n; 69 scanf("%d",&n); 70 for(int i=1;i<=n;i++) { 71 a[i].in(); 72 a[i].f=1; 73 } 74 for(int i=n+1;i<=2*n;i++) { 75 a[i].in(); 76 a[i].f=2; 77 } 78 sort(a+1,a+2*n+1,cmp_x); 79 db ans=F(1,2*n); 80 printf("%.3f\n",ans); 81 } 82 return 0; 83 }