Skip to content

Commit 76bb022

Browse files
committed
Add closest pair
1 parent 0b422cd commit 76bb022

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

cp-algo/geometry/point.hpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#ifndef CP_ALGO_GEOMETRY_POINT_HPP
22
#define CP_ALGO_GEOMETRY_POINT_HPP
3+
#include "../random/rng.hpp"
34
#include <algorithm>
45
#include <iostream>
56
#include <complex>
67
#include <utility>
78
#include <vector>
89
#include <ranges>
10+
#include <map>
911
namespace cp_algo::geometry {
1012
template<typename ftype>
1113
struct point_t: public std::complex<ftype> {
@@ -74,5 +76,53 @@ namespace cp_algo::geometry {
7476
hull.pop_back();
7577
return hull;
7678
}
79+
80+
// Rabin & Lipton
81+
template<typename point>
82+
auto closest_pair(std::vector<point> const& r) {
83+
size_t n = size(r);
84+
int64_t md = 1e18;
85+
for(size_t i = 0; i < n; i++) {
86+
auto A = random::rng() % n;
87+
auto B = random::rng() % n;
88+
if(A != B) {
89+
md = std::min(md, norm(r[A] - r[B]));
90+
if(md == 0) {
91+
return std::pair{A, B};
92+
}
93+
}
94+
}
95+
std::map<point, std::vector<int>> neigs;
96+
md = ceil(sqrtl(md));
97+
for(size_t i = 0; i < n; i++) {
98+
neigs[r[i] / md].push_back(i);
99+
}
100+
size_t a = 0, b = 1;
101+
md = norm(r[a] - r[b]);
102+
for(auto &[p, id]: neigs) {
103+
for(int dx: {-1, 0, 1}) {
104+
for(int dy: {-1, 0, 1}) {
105+
auto pp = p + point{dx, dy};
106+
if(!neigs.count(pp)) {
107+
continue;
108+
}
109+
for(size_t i: neigs[p + point{dx, dy}]) {
110+
for(size_t j: id) {
111+
if(j == i) {
112+
break;
113+
}
114+
int64_t cur = norm(r[i] - r[j]);
115+
if(cur < md) {
116+
md = cur;
117+
a = i;
118+
b = j;
119+
}
120+
}
121+
}
122+
}
123+
}
124+
}
125+
return std::pair{a, b};
126+
}
77127
}
78128
#endif // CP_ALGO_GEOMETRY_POINT_HPP

verify/geometry/closest_pair.test.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// @brief Closest Pair of Points
2+
#define PROBLEM "https://judge.yosupo.jp/problem/closest_pair"
3+
#pragma GCC optimize("Ofast,unroll-loops")
4+
#include "cp-algo/geometry/point.hpp"
5+
#include <bits/stdc++.h>
6+
7+
using namespace std;
8+
using namespace cp_algo::geometry;
9+
using point = point_t<int64_t>;
10+
11+
void solve() {
12+
int n;
13+
cin >> n;
14+
vector<point> r(n);
15+
for(auto &it: r) {
16+
it.read();
17+
}
18+
auto [a, b] = closest_pair(r);
19+
cout << a << ' ' << b << "\n";
20+
}
21+
22+
signed main() {
23+
//freopen("input.txt", "r", stdin);
24+
ios::sync_with_stdio(0);
25+
cin.tie(0);
26+
int t = 1;
27+
cin >> t;
28+
while(t--) {
29+
solve();
30+
}
31+
}

0 commit comments

Comments
 (0)