poj3714 Raid(分治)

题意

给两个点集,求两个点集中任意两点的最小距离。

 

题解

分治+标记

如果会了最近点对问题,就可以做了。
只要在匹配时注意一下不同集合才能匹配就可以了。
我用key做标记:key=1、3表示在集合A,key=2、4在集合B;其中key=1、2表示在a[mid]的左边,key=3、4表示在右边。所以1要和4匹配,2和3匹配。

 

代码

#include
#include
#include
#include
using namespace std;
const double inf=1<<30;
const int maxn=200010;

double dis(double x1,double y1,double x2,double y2)
{
    return sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
}

int n;
struct node
{
    double x,y;
    int key;
}a[maxn],b[maxn];int bn;
bool cmpx(node a1,node a2)
{
    return a1.x>1;
    double d=min(solve(l,mid),solve(mid+1,r));
    
    bn=0;
    for(int i=mid;i>=l && a[mid].x-a[i].x<=d;i--) b[++bn]=a[i];//key->1,2
    for(int i=mid+1;i<=r && a[i].x-a[mid].x<=d;i++) b[++bn]=a[i],b[bn].key+=2;//key->3,4
    
    sort(b+1,b+bn+1,cmpy);
    for(int i=1;i=d) break;
                d=min(d,dis(b[i].x,b[i].y,b[j].x,b[j].y));
            }
        }
    }
    
    return d;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y),a[i].key=1;
        n*=2;
        for(int i=n/2+1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y),a[i].key=2;
        sort(a+1,a+n+1,cmpx);
        double ans=solve(1,n);
        printf("%.3lf\n",ans);
    }
    return 0;
}

 

你可能感兴趣的:(分治)