初学kd树

Posted zhangqingqi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初学kd树相关的知识,希望对你有一定的参考价值。

一开始不会kd树的时候,感觉kd树一定很神,学了kd树发现kd树挺好写。

kd树的每个节点有一个分割超平面,我是以深度%维数作为当前这一维的分割,比较时对于当前节点就比较这一维。

 

附上模板代码,求平面第k近距离(kd树裸题)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cmath>
 7 using namespace std;
 8 #define maxn 100020
 9 #define inf 0x3f3f3f3f3f3f3fll
10 
11 int now;
12 typedef long long ll;
13 struct point{
14     int x[2];
15     bool operator < (point a)const{
16         return x[now] < a.x[now];
17     }
18 }a[maxn];
19 priority_queue <ll> heap;
20 int n,k,id;
21 ll curd;
22 
23 void build(int l,int r,int dep){
24     if ( l > r ) return;
25     now = dep % 2;
26     int mid = (l + r) >> 1;
27     nth_element(a + l,a + mid,a + r + 1);
28     build(l,mid - 1,dep + 1);
29     build(mid + 1,r,dep + 1);
30 }
31 inline ll sqr(int x){ return (ll)x * x; }
32 inline ll dis(int x1,int x2,int y1,int    y2){
33     return sqr(x1 - x2) + sqr(y1 - y2);
34 }
35 void query(point p,int l,int r,int dep){
36     if ( l > r ) return;
37     now = dep % 2;
38     int mid = (l + r) >> 1;
39     ll tmp = dis(p.x[0],a[mid].x[0],p.x[1],a[mid].x[1]);
40     if ( mid > id ){
41         if ( heap.size() < k ) heap.push(tmp);
42         else if ( heap.top() > tmp ){ heap.pop(); heap.push(tmp);}
43     }
44     if ( l == r ) return;
45     if ( p.x[now] > a[mid].x[now] ){
46            query(p,mid + 1,r,dep + 1);
47         now = dep % 2;
48         if ( heap.size() < k || heap.top() >= sqr(p.x[now] - a[mid].x[now]) ) query(p,l,mid - 1,dep + 1);
49     }
50     else{
51         query(p,l,mid - 1,dep + 1);
52         now = dep % 2;
53         if ( heap.size() < k || heap.top() >= sqr(p.x[now] - a[mid].x[now]) ) query(p,mid + 1,r,dep + 1);
54     }
55 }
56 int main(){
57     freopen("star.in","r",stdin);
58     freopen("star.out","w",stdout);
59     scanf("%d %d",&n,&k);
60     for (int i = 1 ; i <= n ; i++){
61         scanf("%d %d",&a[i].x[0],&a[i].x[1]);
62     }
63     build(1,n,1);
64     for (int i = 1 ; i <= n ; i++){
65         id = i;
66         query(a[i],1,n,1);
67     }
68     printf("%lld\n",heap.top());
69     return 0;
70 }

以后多学习kd树的应用,kd树模型可以应用的题的类型。

以上是关于初学kd树的主要内容,如果未能解决你的问题,请参考以下文章

Kd 树迭代实现(C++)

BZOJ 4066 简单题(KD树)

KD树是什么? 为什么要用KD树? KD树怎么用? KD树和KNN的关联是什么?

02-17 kd树

HDU 5992 Finding Hotels(KD树)题解

BZOJ 2648 SJY摆棋子(KD树)