POJ 3714 Raid(平面最近点对)

来源:互联网 发布:淘宝怎么开好直通车 编辑:程序博客网 时间:2024/05/29 15:07

解题思路:

分治法求平面最近点对,点分成两部分,加个标记就好了。

#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <iomanip>#include <string.h>#define LL long longusing namespace std;const int MAXN = 200000 + 10;const double INF = 1e100;struct Point{    double x, y;    int flag;}P[MAXN];int N;Point vec[MAXN];bool cmp_x(Point a, Point b){    return a.x < b.x;}bool cmp_y(Point a, Point b){    return a.y < b.y;}double dis(Point a, Point b){    double dx = a.x - b.x;    double dy = a.y - b.y;    return sqrt(dx * dx + dy * dy);}double solve(Point *a, int l, int r){    if(l == r) return INF;    if(l + 1 == r)    {        if(P[l].flag == P[r].flag)            return INF;        return dis(P[l], P[r]);    }    int m = (l + r) >> 1;    double d = solve(a, l, m);    d = min(d, solve(a, m + 1, r));    int sz = 0;    for(int i=l;i<=r;i++)    {        if(fabs(P[i].x - P[m].x) <= d)            vec[sz++] = P[i];    }    sort(vec, vec + sz, cmp_y);    for(int i=0;i<sz;i++)    {        for(int j=i+1;j<sz;j++)        {            if(fabs(vec[i].y - vec[j].y) >= d)                break;            if(vec[i].flag != vec[j].flag)            {                double rs = dis(vec[i], vec[j]);                if(rs < d) d = rs;            }        }    }    return d;}int main(){    int T;    scanf("%d", &T);    while(T--)    {        scanf("%d", &N);        for(int i=0;i<N;i++)        {            scanf("%lf%lf", &P[i].x, &P[i].y);            P[i].flag = 0;        }        for(int i=0;i<N;i++)        {            scanf("%lf%lf", &P[i + N].x, &P[i + N].y);            P[i + N]. flag = 1;        }        N <<= 1;        sort(P, P + N, cmp_x);        double ans = solve(P, 0, N - 1);        printf("%.3f\n", ans);    }    return 0;}

0 0