最近点对算法模板

#include<algorithm>
using namespace std;
#define maxs 200005
struct Point
{
    double x,y;
}point[maxs];
int y_sort[maxs];
int cmpx(Point a,Point b)//按照x对这些点从小到大排序
{
    return a.x<b.x;
}
int cmpy(int a,int b)//对最近点算法中的y_sort数组排序
{
    return point[a].y<point[b].y;
}
double dis(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
/*
    最近点对算法,在point[first]--point[last]个点中寻找一个最短距离
    使用该算法前先对这些点排序
    sort(point,point+n,cmpx);
*/
double findMin(int first, int last)
{
    if((last-first)==1)
        return dis(point[first],point[last]);
    else if(last-first==2)
    {
        double d1 = dis(point[first],point[first+1]);
        double d2 = dis(point[first],point[first+2]);
        double d3 = dis(point[first+1],point[first+2]);
        return min(min(d1,d2),d3);
    }
    //二分
    int mid = (first+last)/2;
    double min_dist = min(findMin(first,mid),findMin(mid+1,last));
    if(min_dist==0)
        return 0;
    int y_end = 0;
    for(int i=mid;point[mid].x-point[i].x<min_dist&&i>=first;i--)
        y_sort[y_end++]=i;
    for(int i=mid+1;point[i].x-point[mid+1].x<min_dist&&i<=last;i++)
        y_sort[y_end++]=i;
    sort(y_sort,y_sort+y_end,cmpy);
    for(int i=0;i<y_end;i++)
        for(int j=i+1;j<y_end&&(point[y_sort[j]].y-point[y_sort[i]].y)<min_dist;j++)
            min_dist=min(min_dist,dis(point[y_sort[i]],point[y_sort[j]]));
    return min_dist;

}

poj3714

题目大意:

有若干车站和加油站,求车站和加油站的最小距离.

思路:

求最近点对,注意的是需要对车站和加油站分类,同类的话就初始化为INF

这样就不会找到相同类间的距离了,从而只会得到车站和加油站的最小距离

#include <iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxs 200005
#define INF 1e100
struct Point
{
    double x,y;
    bool flag;
}point[maxs];
int y_sort[maxs];
int cmpx(Point a,Point b)//按照x对这些点从小到大排序
{
    return a.x<b.x;
}
int cmpy(int a,int b)//对最近点算法中的y_sort数组排序
{
    return point[a].y<point[b].y;
}
double dis(Point a,Point b)
{
    if(a.flag!=b.flag)
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    return INF;//是同一类,初始化为无穷大,这样最近点对算法就不会找同类的最短距离
}
/*
    最近点对算法,在point[first]--point[last]个点中寻找一个最短距离
    使用该算法前先对这些点排序
    sort(point,point+n,cmpx);
*/
double findMin(int first, int last)
{
    if((last-first)==1)
        return dis(point[first],point[last]);
    else if(last-first==2)
    {
        double d1 = dis(point[first],point[first+1]);
        double d2 = dis(point[first],point[first+2]);
        double d3 = dis(point[first+1],point[first+2]);
        return min(min(d1,d2),d3);
    }
    //二分
    int mid = (first+last)/2;
    double min_dist = min(findMin(first,mid),findMin(mid+1,last));
    if(min_dist==0)
        return 0;
    int y_end = 0;
    for(int i=mid;point[mid].x-point[i].x<min_dist&&i>=first;i--)
        y_sort[y_end++]=i;
    for(int i=mid+1;point[i].x-point[mid+1].x<min_dist&&i<=last;i++)
        y_sort[y_end++]=i;
    sort(y_sort,y_sort+y_end,cmpy);
    for(int i=0;i<y_end;i++)
        for(int j=i+1;j<y_end&&(point[y_sort[j]].y-point[y_sort[i]].y)<min_dist;j++)
            min_dist=min(min_dist,dis(point[y_sort[i]],point[y_sort[j]]));
    return min_dist;

}
int main()
{
    //freopen("in.txt","r",stdin);
    int T,n;
    cin>>T;
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf",&point[i].x,&point[i].y);
            point[i].flag=true;
        }
        for(int i=n;i<2*n;i++)
        {
            scanf("%lf%lf",&point[i].x,&point[i].y);
            point[i].flag=false;
        }
        n=2*n;
        sort(point,point+n,cmpx);//排序
        double ans = findMin(0,n-1);
        printf("%0.3f
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wt20/p/5803349.html