```struct point
{
double x,y;
int id;
//int flag;
point(double x=0,double y =0):x(x),y(y) {}
} p[N],pp[N],py[N];
typedef point pointt;
pointt operator -(point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
double dis(point a,point b)
{
// if(a.flag==b.flag) return INF;//适于两种不同点集间的最小距离
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(point a,point b)
{
return a.x<b.x;
}
bool cmpp(point a,point b)
{
return a.y<b.y;
}
void binmerge(point py[],point pp[],int l,int m,int r)
{
int i,j,g=l;
for(i = l,j = m+1 ; i <= m&&j <= r ;)//将pp中两块有序的集合 合并为一个有序的集合
if(pp[i].y<pp[j].y) py[g++] = pp[i++];
else py[g++] = pp[j++];

while(i<=m) py[g++] = pp[i++];
while(j<=r) py[g++] = pp[j++];
//memcpy(pp + l, py + l, (r - l + 1) *sizeof(py[0]));
}
double binshortest(point p[],point pp[],point py[],int l,int r)
{
if(r-l==1) return dis(p[l],p[r]);
if(r-l==2) return min(min(dis(p[l],p[r]),dis(p[l],p[l+1])),dis(p[l+1],p[r]));
int mid = (l+r)>>1;
int i,j,g = l,o = mid+1;
for(i = l ; i <= r ; i++)
{
if(py[i].id<=mid)//按y坐标顺序将点划分到pp左半数组
pp[g++] = py[i];
else
pp[o++] = py[i];//pp右半数组
}
double minz = min(binshortest(p,py,pp,l,mid),binshortest(p,py,pp,mid+1,r));
binmerge(py,pp,l,mid,r);
g = l;
for(i = l ; i <= r ; i++)//找到x坐标满足到中心线距离小于minz的点
if(fabs(py[i].x-py[mid].x)<minz) pp[g++] = py[i];
for(i = l ; i < g ; i++)
{
for(j = i+1 ; j < g && fabs(pp[i].y-pp[j].y)<minz; j++)//加上y坐标上的限制
minz = min(dis(pp[i],pp[j]),minz);
}
return minz;
}
void solve(point p[])
{
sort(p,p+n,cmp);
for(int i = 0; i < n ; i++)
p[i].id = i;
memcpy(py,p,n*sizeof(py[0]));
sort(p,p+n,cmpp);
double ans = binshortest(p,pp,py,0,n-1);
}```

例题

hdu1007  直接模板

poj3714  两种点集间的