【计算几何】平面最近点对
复杂度确定的分治算法(还带有一个最优性剪枝)
const int MAXN = 2e5 + 10;
const double MAXDIS = 1e20;
int n;
struct Point {
double x, y;
} p[MAXN];
double calc(int l, int r, double res) {
static auto dis = [](int i, int j) {
double x = (p[i].x - p[j].x) * (p[i].x - p[j].x);
double y = (p[i].y - p[j].y) * (p[i].y - p[j].y);
return sqrt(x + y);
};
if (r - l + 1 <= 4) {
for (int i = l; i <= r; ++i) {
for (int j = i + 1; j <= r; ++j)
res = min(res, dis(i, j));
}
return res;
}
static int tmp[MAXN];
int mid = (l + r) / 2, top = 0;
res = min(res, calc(l, mid, res));
res = min(res, calc(mid + 1, r, res));
for (int i = l; i <= r; ++i) {
if (abs(p[mid].x - p[i].x) < res)
tmp[++top] = i;
}
sort(tmp + 1, tmp + 1 + top, [](const int &a, const int &b) {
return p[a].y < p[b].y;
});
for (int i = 1; i <= top; ++i) {
for (int j = i + 1; j <= top; ++j) {
if (p[tmp[j]].y - p[tmp[i]].y >= res)
break;
res = min(res, dis(tmp[i], tmp[j]));
}
}
return res;
}
double getClosestDistance(int n) {
sort(p + 1, p + 1 + n, [](const Point & a, const Point & b) {
return (a.x != b.x) ? a.x < b.x : a.y < b.y;
});
return calc(1, n, MAXDIS);
}
void solve() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%lf%lf", &p[i].x, &p[i].y);
printf("%.12f\n", getClosestDistance(n));
return;
}
练习