题意:station和agent分别有n(1<=n<=100000)个点,求不同类别的最近点对距离。
题解:http://blog.csdn.net/w397090770/article/details/7295797 这里讲的很好。
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#include <cmath>
#define MAX(a , b) ((a) > (b) ? (a) : (b))
#define MIN(a , b) ((a) < (b) ? (a) : (b))
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
using namespace std;
const double inf = 1e50;
const int maxn = 100002;
struct P
{
double x,y;
int type;
}po[maxn << 1];
int middle[maxn << 1];
int n;
bool cmpx(P a,P b)
{
return a.x < b.x;
}
bool cmpy(int a,int b)
{
return po[a].y < po[b].y;
}
void read()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf %lf",&po[i].x,&po[i].y);
po[i].type = 0;
}
for(int i=n;i<2*n;i++)
{
scanf("%lf %lf",&po[i].x,&po[i].y);
po[i].type = 1;
}
n <<= 1;
sort(po , po+n , cmpx);
return;
}
double dis(int i,int j)
{
if(po[i].type == po[j].type) return inf;
return sqrt((po[i].x - po[j].x) * (po[i].x - po[j].x) + (po[i].y - po[j].y) * (po[i].y - po[j].y));
}
double Mindis(int l,int r)
{
if(l >= r-1) return dis(l , r);
int mid = (l + r) >> 1;
double a = Mindis(l , mid);
double b = Mindis(mid+1 , r);
double d = MIN(a , b);
int top = 0;
for(int i=l;i<=r;i++)
{
if(ABS(po[i].x - po[mid].x) <= d)
{
middle[top++] = i;
}
}
sort(middle , middle + top , cmpy);
for(int i=0;i<top;i++)
{
int to = MIN(top-1 , i+6);
for(int j=i+1;j<=to;j++)
{
d = MIN(d , dis(middle[i] , middle[j]));
}
}
return d;
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
read();
printf("%.3f\n",Mindis(0,n-1));
}
return 0;
}