本文参考:

https://www.cnblogs.com/GerynOhenz/p/8727415.html

kuangbin的ACM模板(新)


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4347

Problem Description

The course of Software Design and Development Practice is objectionable. ZLC is facing a serious problem .There are many points in K-dimensional space .Given a point. ZLC need to find out the closest m

points. Euclidean distance is used as the distance metric between two points. The Euclidean distance between points p and q is the length of the line segment connecting them.In Cartesian coordinates, if p =

(p1, p2,..., pn) and q = (q1, q2,..., qn) are two points in Euclidean n-space, then the distance from p to q, or from q to p is given by:

$d\left( {{\bf{p}},{\bf{q}}} \right) = d\left( {{\bf{q}},{\bf{p}}} \right) = \sqrt {\sum\limits_{i = 1}^n {\left( {p_i - q_i } \right)^2 } }$

Can you help him solve this problem?

Input

In the first line of the text file. There are two non-negative integers n and K. They denote respectively: the number of points, 1 <= n <= 50000, and the number of Dimensions, 1 <= K <= 5. In each of the following n lines there is written K integers, representing the coordinates of a point. This followed by a line with one positive integer t, representing the number of queries, 1 <= t <=10000.

Each query contains two lines. The k integers in the first line represent the given point. In the second line, there is one integer m, the number of closest points you should find,1 <= m <=10. The absolute value of all the coordinates will not be more than 10000. There are multiple test cases. Process to end of file.

Output

For each query, output m+1 lines:

The first line saying :”the closest m points are:” where m is the number of the points.

The following m lines representing m points ,in accordance with the order from near to far

It is guaranteed that the answer can only be formed in one ways. The distances from the given point to all the nearest m+1 points are different. That means input like this:

2 2
1 1
3 3
1
2 2
1

will not exist.

Sample Input
3 2
1 1
1 3
3 4
2
2 3
2
2 3
1

Sample Output
the closest 2 points are:
1 3
3 4
the closest 1 points are:
1 3

题意:

给出 $n$ 个 $K$ 维的点,又给出 $t$ 个查询, 每个查询也给出一个 $K$ 维的点,要求查询 $n$ 个点中距离这个点最近的 $M$ 个点。

题解:

KDTree模板题。


以下关于KDTree的小记:

1、简介

KDTree(K-dimensional tree) 是一个支持多维空间的数据结构,主要是将空间内的点进行区域划分,快速维护有关空间点的操作,例如空间的最远(近)点对,区间搜索。

KDTree 的结构与线段树类似,只是线段树是对一维空间的操作,而 KDTree 是多维操作的,这也导致了 KDTree 的灵活性没有线段树高。

树上每个节点所维护的信息:

  1. 左右两个儿子
  2. 该点表示的空间范围(超长方体,当 $K=2$ 时为矩形,$K=3$ 时为长方体)
  3. 中位点(坐标等信息)

2.1、建树

假设我们已经有了一个描述 $K$ 维空间内的点的类Point,且我们已经有Point类型的 $a[0:n-1]$ 数组。

首先因为是空间划分,所以要循环递进地用垂直于各维度轴的超平面(或者线、平面)进行划分。

例如在二维平面上的划分,先用垂直 $x$ 轴的直线进行划分,再用垂直 $y$ 轴的直线进行划分,再用垂直 $x$ 轴的直线进行划分……

那么,假设现在要用垂直 $x$ 轴的直线划分在 $a[0:n-1]$ 数组内某个整数区间 $[l,r)$ 上的这些点,

首先初始化该点的空间范围,假设 $mid = \left\lfloor {\frac{{l + r}}{2}} \right\rfloor$,作为 $[l,r)$ 按 $x$ 坐标从小到大排序时的中位点位置,

然后用 nth_element(st,st+n,ed) 线性时间复杂度地将 $[l,r)$ 分成了  $[l,mid)$ 和 $[mid+1,r)$ 两部分,而 $a[mid]$ 则存储了中位点,

然后递归两个区间(作为左右儿子),当然,这两个区间则要用垂直 $y$ 轴的直线进行划分,以此类推。

(其中,调用 nth_element(st,st+n,ed) 方法可以求得 $[st,ed)$ 区间内所有元素中第 $n$ 小的元素,并把它放在第 $n$ 个位置上。注意,下标是从 $st+0$ 开始计数的,也就是说求第 $0$ 小的元素就是最小的数,同样地,第 $0$ 个位置是最前面的位置。)

举例:

2.2、查询 $k$ 近邻

$k$ 近邻是指找到第 $k$ 近的点,需要维护一个大顶堆,维护当前 $k$ 个点中的最远距离,如果当前点比最远距离要小,则更新大根堆,而且利用最远距离可以减掉那些不在当前第 $k$ 距离内的区间。


AC代码:

  1. #include<bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. using namespace std;
  5.  
  6. const int maxn=5e4+;
  7. const int maxk=;
  8. int k,idx;
  9. struct Point
  10. {
  11. int x[maxk];
  12. bool operator<(const Point &o)const
  13. {
  14. return x[idx]<o.x[idx];
  15. }
  16. void print()
  17. {
  18. for(int i=;i<k;i++) printf("%d%c",x[i],(i==k-)?'\n':' ');
  19. }
  20. }poi[maxn];
  21. typedef pair<double,Point> P;
  22. priority_queue<P> Q;
  23. void clear(priority_queue<P> &Q)
  24. {
  25. if(Q.empty()) return;
  26. priority_queue<P> tp;
  27. swap(Q,tp);
  28. }
  29. struct kdTree
  30. {
  31. #define sqr(x) ((x)*(x))
  32. #define ls (rt<<1)
  33. #define rs (rt<<1|1)
  34. Point o[maxn<<];
  35. int son[maxn<<];
  36.  
  37. void build(int rt,int l,int r,int dep)
  38. {
  39. if(l>r) return;
  40. son[rt]=r-l, son[ls]=son[rs]=-;
  41. idx=dep%k;
  42. int mid=(l+r)>>;
  43. nth_element(poi+l,poi+mid,poi+r+);
  44. o[rt]=poi[mid];
  45. build(ls,l,mid-,dep+);
  46. build(rs,mid+,r,dep+);
  47. }
  48. void query(int rt,Point p,int m,int dep)
  49. {
  50. if(son[rt]==-) return;
  51. P nd(,o[rt]);
  52. for(int i=;i<k;i++) nd.fi+=sqr(nd.se.x[i]-p.x[i]);
  53. int dim=dep%k, x=ls, y=rs; bool fg=;
  54. if(p.x[dim]>=o[rt].x[dim]) swap(x,y);
  55. if(~son[x]) query(x,p,m,dep+);
  56. if(Q.size()<m) Q.push(nd), fg=;
  57. else
  58. {
  59. if(nd.fi<Q.top().fi) Q.pop(), Q.push(nd);
  60. if(sqr(p.x[dim]-o[rt].x[dim])<Q.top().fi) fg=;
  61. }
  62. if(~son[y] && fg) query(y,p,m,dep+);
  63. }
  64. }kdt;
  65.  
  66. int n;
  67. int main()
  68. {
  69. while(cin>>n>>k)
  70. {
  71. for(int i=;i<n;i++) for(int j=;j<k;j++) scanf("%d",&(poi[i].x[j]));
  72. kdt.build(,,n-,);
  73.  
  74. int t; cin>>t;
  75. stack<Point> ans;
  76. while(t--)
  77. {
  78. Point qry;
  79. for(int i=;i<k;i++) scanf("%d",&qry.x[i]);
  80. int m; scanf("%d",&m);
  81.  
  82. clear(Q);
  83. kdt.query(,qry,m,);
  84.  
  85. printf("the closest %d points are:\n",m);
  86. while(Q.size()) ans.push(Q.top().se), Q.pop();
  87. while(ans.size()) ans.top().print(), ans.pop();
  88. }
  89. }
  90. }

HDU 4347 - The Closest M Points - [KDTree模板题]的更多相关文章

  1. bzoj 3053 HDU 4347 : The Closest M Points kd树

    bzoj 3053 HDU 4347 : The Closest M Points  kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差 ...

  2. hud 4347 The Closest M Points(KD-Tree)

    传送门 解题思路 \(KD-Tree\)模板题,\(KD-Tree\)解决的是多维问题,它是一个可以储存\(K\)维数据的二叉树,每一层都被一维所分割.它的插入删除复杂度为\(log^2 n\),它查 ...

  3. HDU 4347 The Closest M Points (kdTree)

    赤果果的kdTree. 学习传送门:http://www.cnblogs.com/v-July-v/archive/2012/11/20/3125419.html 其实就是二叉树的变形 #includ ...

  4. hdu 4347 The Closest M Points (kd树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4347 题意: 求k维空间中离所给点最近的m个点,并按顺序输出  . 解法: kd树模板题 . 不懂kd树的可以先看看这个 . 不多说, ...

  5. 数据结构(KD树):HDU 4347 The Closest M Points

    The Closest M Points Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Ot ...

  6. hdu 4347 The Closest M Points(KD树)

    Problem - 4347 一道KNN的题.直接用kd树加上一个暴力更新就撸过去了.写的时候有一个错误就是搜索一边子树的时候返回有当前层数会被改变了,然后就直接判断搜索另一边子树,搞到wa了半天. ...

  7. 洛谷 P4148 简单题 KD-Tree 模板题

    Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...

  8. hdu4347The Closest M Points kdtree

    kdtree讲解: https://blog.csdn.net/qing101hua/article/details/53228668 https://blog.csdn.net/acdreamers ...

  9. 【HDOJ】4347 The Closest M Points

    居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...

随机推荐

  1. Sql Server 阻塞的常见原因和解决办法

    1. 由于语句运行时间太长而导致的阻塞,语句本身在正常运行中,只须等待某些系统资源 解决办法: a. 语句本身有没有可优化的空间 b. Sql Server 整体性能如何,是不是有资源瓶颈影响了语句执 ...

  2. Shell脚本编程(二):shell变量

    定义变量 定义变量时,变量名不加美元符号($,PHP语言中变量需要),如: your_name="runoob.com" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程 ...

  3. GCD使用:让程序在后台较长久的运行(UIBackgroundTaskIdentifier )

        在没有使用GCD时,当app被按home键退出后,app仅有最多5秒钟的时候做一些保存或清理资源的工作.但是在使用GCD后,app最多有10分钟的时间在后台长久运行.这个时间可以用来做清理本地 ...

  4. Fluent动网格【1】:概述

    最近总有小伙伴向我询问Fluent中的动网格问题,因此决定做一期关于Fluent动网格技术的内容. 动网格技术在流体仿真中很特殊,应用也很广.生活中能够碰到形形色色的包含有部件运动的问题,比如说我现在 ...

  5. Halcon例程detect_indent_fft学习

    ************************************************************************************************ *** ...

  6. 在linux环境下编译android so库

    (1) 配置Android NDK环境 (2) mk文件编写 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # OpenCV OPENCV_CA ...

  7. 概率霍夫变换(Progressive Probabilistic Hough Transform)原理详解

    概率霍夫变换(Progressive Probabilistic Hough Transform)的原理很简单,如下所述: 1.随机获取边缘图像上的前景点,映射到极坐标系画曲线: 2.当极坐标系里面有 ...

  8. Oracle Enterprise Linux 6.4 下配置vncserver

    ① 安装vncserveryum install tigervnc-server ② 配置/etc/sysconfig/vncservers   配置参数   # VNCSERVERS="2 ...

  9. centos7 centos中apache运行php需要连接mysql一直连不上,telnet访问mysql出错Connection closed by foreign host

    执行命令: getsebool -a|grep httpd 发现 httpd_can_network_connect off 解决:  setsebool httpd_can_network_conn ...

  10. Flask框架(2)-JinJa2模板

    为了把业务逻辑和表现逻辑分开,Flask把表现逻辑移到JinJa2模板,模板是一个包含响应文本的文件.它用占位变量表示动态部分,其具体要从请求上下文才知道. 把真实值替换掉占位变量成为渲染,JinJa ...