-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkd_tree1.cpp
More file actions
104 lines (90 loc) · 2.33 KB
/
kd_tree1.cpp
File metadata and controls
104 lines (90 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
const int maxn = 100000;
int tx[maxn];
int ty[maxn];
bool divX[maxn];
bool cmpX(const pii &a, const pii &b) {
return a.first < b.first;
}
bool cmpY(const pii &a, const pii &b) {
return a.second < b.second;
}
void buildTree(int left, int right, pii points[]) {
if(left >= right){
return;
}
int mid = (left + right) >> 1;
//sort(points + left, points + right + 1, divX ? cmpX : cmpY);
int minx = INT_MAX;
int maxx = INT_MIN;
int miny = INT_MAX;
int maxy = INT_MIN;
for(int i = left; i < right; i++) {
min(minx, points[i].first);
max(maxx, points[i].first);
min(miny, points[i].second);
max(maxy, points[i].second);
}
divX[mid] = (maxx - minx) >= (maxy - miny);
nth_element(points + left, points + mid, points + right, divX[mid] ? cmpX : cmpY);
tx[mid] = points[mid].first;
ty[mid] = points[mid].second;
if(left + 1 == right){
return;
}
buildTree(left, mid, points);
buildTree(mid + 1, right, points);
}
long long closestDist;
int closestNode;
void findNearestNeighbour(int left, int right, int x, int y){
if(left >= right){
return;
}
int mid = (left + right) >> 1;
int dx = x - tx[mid];
int dy = y - ty[mid];
long long d = dx * (long long) dx + dy * (long long) dy;
if(closestDist > d && d){
closestDist = d;
closestNode = mid;
}
if(left + 1 == right){
return;
}
int delta = divX[mid] ? dx : dy;
long long delta2 = delta * (long long) delta;
int l1 = left;
int r1 = mid;
int l2 = mid + 1;
int r2 = right;
if(delta > 0){
swap(l1, l2), swap(r1, r2);
}
findNearestNeighbour(l1, r1, x, y);
if(delta2 < closestDist){
findNearestNeighbour(l2, r2, x, y);
}
}
int findNearestNeighbour(int n, int x, int y){
closestDist = LLONG_MAX;
findNearestNeighbour(0, n, x, y);
return closestNode;
}
int main()
{
vpii p;
p.push_back(make_pair(0, 2));
p.push_back(make_pair(0, 3));
p.push_back(make_pair(-1, 0));
p.resize(unique(p.begin(), p.end()) - p.begin());
int n = p.size();
buildTree(0, n - 1, &(vpii(p)[0]));
int res = findNearestNeighbour(n, 0, 0);
cout << p[res].first << " " << p[res].second << endl;
cout << closestDist << endl;
return 0;
}