bryce1010專題——KD-Tree
bryce1010專題——KD-Tree
【KD-Tree模板題】
HDU-4347 The Closest M Points
http://acm.hdu.edu.cn/showproblem.php?pid=4347
【題意】
求一個點的最近M個點。
(1=<n<=50000,1=<t<=10000)
【思路】
KD-Tree
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <queue>
using namespace std;
#define N 50005
#define lson rt << 1
#define rson rt << 1 | 1
#define Pair pair<double, Node>
#define Sqrt2(x) (x) * (x)
int n, k, idx;
struct Node
{
int feature[5]; //定義屬性陣列
bool operator < (const Node &u) const
{
return feature[idx] < u.feature[idx];
}
}_data[N]; //_data[]陣列代表輸入的資料
priority_queue<Pair> Q; //佇列Q用於存放離p最近的m個數據
class KDTree{
public:
void Build(int, int, int, int); //建樹
void Query(Node, int, int, int); //查詢
private:
Node data[4 * N] ; //data[]陣列代表K-D樹的所有節點資料
int flag[4 * N]; //用於標記某個節點是否存在,1表示存在,-1表示不存在
}kd;
//建樹步驟,引數dept代表樹的深度
void KDTree::Build(int l, int r, int rt, int dept)
{
if(l > r) return;
flag[rt] = 1; //表示編號為rt的節點存在
flag[lson] = flag[rson] = -1; //當前節點的孩子暫時標記不存在
idx = dept % k; //按照編號為idx的屬性進行劃分
int mid = (l + r) >> 1;
nth_element(_data + l, _data + mid, _data + r + 1); //nth_element()為STL中的函式
data[rt] = _data[mid];
Build(l, mid - 1, lson, dept + 1); //遞迴左子樹
Build(mid + 1, r, rson, dept + 1); //遞迴右子樹
}
//查詢函式,尋找離p最近的m個特徵屬性
void KDTree::Query(Node p, int m, int rt, int dept)
{
if(flag[rt] == -1) return; //不存在的節點不遍歷
Pair cur(0, data[rt]); //獲取當前節點的資料和到p的距離
for(int i = 0; i < k; i++)
cur.first += Sqrt2(cur.second.feature[i] - p.feature[i]);
int dim = dept % k; //跟建樹一樣,這樣能保證相同節點的dim值不變
bool fg = 0; //用於標記是否需要遍歷右子樹
int x = lson;
int y = rson;
if(p.feature[dim] >= data[rt].feature[dim]) //資料p的第dim個特徵值大於等於當前的資料,則需要進入右子樹
swap(x, y);
if(~flag[x]) Query(p, m, x, dept + 1); //如果節點x存在,則進入子樹繼續遍歷
//以下是回溯過程,維護一個優先佇列
if(Q.size() < m) //如果佇列沒有滿,則繼續放入
{
Q.push(cur);
fg = 1;
}
else
{
if(cur.first < Q.top().first) //如果找到更小的距離,則用於替換佇列Q中最大的距離的資料
{
Q.pop();
Q.push(cur);
}
if(Sqrt2(p.feature[dim] - data[rt].feature[dim]) < Q.top().first)
{
fg = 1;
}
}
if(~flag[y] && fg)
Query(p, m, y, dept + 1);
}
//輸出結果
void Print(Node data)
{
for(int i = 0; i < k; i++)
printf("%d%c", data.feature[i], i == k - 1 ? '\n' : ' ');
}
int main()
{
while(scanf("%d%d", &n, &k)!=EOF)
{
for(int i = 0; i < n; i++)
for(int j = 0; j < k; j++)
scanf("%d", &_data[i].feature[j]);
kd.Build(0, n - 1, 1, 0);
int t, m;
scanf("%d", &t);
while(t--)
{
Node p;
for(int i = 0; i < k; i++)
scanf("%d", &p.feature[i]);
scanf("%d", &m);
while(!Q.empty()) Q.pop(); //事先需要清空優先佇列
kd.Query(p, m, 1, 0);
printf("the closest %d points are:\n", m);
Node tmp[25];
for(int i = 0; !Q.empty(); i++)
{
tmp[i] = Q.top().second;
Q.pop();
}
for(int i = m - 1; i >= 0; i--)
Print(tmp[i]);
}
}
return 0;
}
【KD-Tree模板】
HDU2966 In case of failure
http://acm.hdu.edu.cn/showproblem.php?pid=2966
【題意】
給n個二維點,求每個點距離其它點最近的距離。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
final static int SIZE = 100005;
final static double EPS = 1e-10;
private boolean[] d = null;
private Node[] p = null;
private long res;
private int index;
private int size;
public class Node{
private long[] x = null;
Node(){
x = new long[2];
}
}
Main(int size){
d = new boolean[size];
p = new Node[size];
for(int i = 0; i < size; i++)
p[i] = new Node();
}
public void setSize(int size){
this.size = size;
Arrays.fill(d, false);
}
public void clear(){
res = Long.MAX_VALUE;
index = 0;
}
public void Insert(int id, Node t){
p[id] = t;
}
public Node get(int id){
return p[id];
}
public void InsertSort(Node a[], int id, int l, int r){
for(int i = l + 1; i <= r; i++){
if(a[i - 1].x[id] > a[i].x[id]){
Node t = new Node();
t = a[i];
int j = i;
while(j > l && a[j - 1].x[id] > t.x[id])
{
a[j] = a[j - 1];
j--;
}
a[j] = t;
}
}
}
public Node FindMid(Node a[], int id, int l, int r)
{
if(l == r) return a[l];
int i = 0;
int n = 0;
for(i = l; i < r - 5; i += 5)
{
InsertSort(a, id, i, i + 4);
n = i - l;
Node t = new Node();
t = a[l + n / 5];
a[l + n / 5] = a[i + 2];
a[i + 2] = t;
}
int num = r - i + 1;
if(num > 0)
{
InsertSort(a, id, i, i + num - 1);
n = i - l;
Node t = new Node();
t = a[l + n / 5];
a[l + n / 5] = a[i + num / 2];
a[i + num / 2] = t;
}
n /= 5;
if(n == l) return a[l];
return FindMid(a, id, l, l + n);
}
public boolean Equals(Node a, Node b){
if(Math.abs(a.x[0] - b.x[0]) > EPS)
return false;
if(Math.abs(a.x[1] - b.x[1]) > EPS)
return false;
return true;
}
public int FindId(Node a[], int l, int r, Node num)
{
for(int i = l; i <= r; i++)
if(Equals(a[i], num))
return i;
return -1;
}
public int Partion(Node a[], int id, int l, int r, int p)
{
Node t = new Node();
t = a[p];
a[p] = a[l];
a[l] = t;
int i = l;
int j = r;
Node pivot = a[l];
while(i < j)
{
while(a[j].x[id] >= pivot.x[id] && i < j)
j--;
a[i] = a[j];
while(a[i].x[id] <= pivot.x[id] && i < j)
i++;
a[j] = a[i];
}
a[i] = pivot;
return i;
}
public Node BFPTR(Node a[], int id, int l, int r, int k)
{
if(l > r) return null;
Node num = FindMid(a, id, l, r);
int p = FindId(a, l, r, num);
int i = Partion(a, id, l, r, p);
int m = i - l + 1;
if(m == k) return a[i];
if(m > k) return BFPTR(a, id, l, i - 1, k);
return BFPTR(a, id, i + 1, r, k - m);
}
public Node getInterval(Node p[], int id, int l, int r){
Node t = new Node();
long max = Long.MIN_VALUE;
long min = Long.MAX_VALUE;
for(int i = l; i <= r; i++){
if(max < p[i].x[id]) max = p[i].x[id];
if(min > p[i].x[id]) min = p[i].x[id];
}
t.x[0] = min;
t.x[1] = max;
return t;
}
public long getDist(Node a, Node b){
return (a.x[0] - b.x[0]) * (a.x[0] - b.x[0]) + (a.x[1] - b.x[1]) * (a.x[1] - b.x[1]);
}
public void Build(Node p[], int l, int r){
if(l > r) return;
Node t1 = getInterval(p, 0, l, r);
long minx = t1.x[0];
long maxx = t1.x[1];
Node t2 = getInterval
相關推薦
bryce1010專題——KD-Tree
bryce1010專題——KD-Tree
【KD-Tree模板題】 HDU-4347 The Closest M Points http://acm.hdu.edu.cn/showproblem.php?pid=4347 【題意】 求一個點的最近M個點。 (1=<n<=5
【bzoj1941】[Sdoi2010]Hide and Seek KD-tree
地形 容易 輸入一個整數 坐標 highlight 最小值 水平 簡單 一個點 題目描述
小豬iPig在PKU剛上完了無聊的豬性代數課,天資聰慧的iPig被這門對他來說無比簡單的課弄得非常寂寞,為了消除寂寞感,他決定和他的好朋友giPi(雞皮)玩一個更加寂寞的遊戲---捉
【bzoj2850】巧克力王國 KD-tree
維護 microsoft cor printf ace 但是 urn ans else 題目描述
巧克力王國裏的巧克力都是由牛奶和可可做成的。但是並不是每一塊巧克力都受王國人民的歡迎,因為大家都不喜歡過於甜的巧克力。對於每一塊巧克力,我們設x和y為其牛奶和可可的含量。由於
【BZOJ3489】A simple rmq problem kd-tree
while 長度 {} per tput amp 可能 ans bzoj3489 【BZOJ3489】A simple rmq problem
Description
因為是OJ上的題,就簡單點好了。給出一個長度為n的序列,給出M個詢問:在[l,r]之間找到一個在這
【bzoj2989】數列 KD-tree
數據 ++ class microsoft 出現 cpp ros int 所有 題目描述
給定一個長度為n的正整數數列a[i]。
定義2個位置的graze值為兩者位置差與數值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|。
2種操作(k都是正整
【bzoj4605】嶗山白花蛇草水 權值線段樹套KD-tree
復雜 接下來 efi ora 這也 多少 線段樹 會有 如果 題目描述
神犇Aleph在SDOI Round2前立了一個flag:如果進了省隊,就現場直播喝嶗山白花蛇草水。憑借著神犇Aleph的實力,他輕松地進了山東省省隊,現在便是他履行諾言的時候了。蒟蒻Bob特地為他準
【BZOJ4605】嶗山白花蛇草水 權值線段樹+kd-tree
現在 ive blog 次數 pan std highlight 解釋 pac 【BZOJ4605】嶗山白花蛇草水
Description
神犇Aleph在SDOI Round2前立了一個flag:如果進了省隊,就現場直播喝嶗山白花蛇草水。憑借著神犇Aleph的實力
【BZOJ2626】JZPFAR kd-tree+堆
long long print prior ros strong led queue 整數 cond 【BZOJ2626】JZPFAR
Description
平面上有n個點。現在有m次詢問,每次給定一個點(px, py)和一個整數k,輸出n個點中離(px,
【bzoj2626】JZPFAR KD-tree+堆
左右 clu 替換 坐標 元素 util light amp nbsp 題目描述
平面上有n個點。現在有m次詢問,每次給定一個點(px, py)和一個整數k,輸出n個點中離(px, py)的距離第k大的點的標號。如果有兩個(或多個)點距離(px, py)相同,那麽認為
hdu 2966 In case of failure(KD-tree)
-- pri include while failure ref element spl define 題目鏈接:hdu 2966 In case of failure
題意:
給你n個點,讓你輸出每個點到最近點的歐式距離。
題解:
KD-樹裸題,板子抄的鳥神的。
1
【模板】超強KD-Tree模板
mem def closed con fin close long 之前 strong 之所以說超強,是因為這個模板又短(我見過最短的kdtree)跑得又快(我用來寫了某道題在vj上跑了第一)也易於修改(之前拿某個大板子來改,不僅不好改而且改了跑得賊慢)。無需初始化任何變量
BZOJ 2648 SJY擺棋子(KD Tree)
tor air math space min void php class sta http://www.lydsy.com/JudgeOnline/problem.php?id=2648
題意:
思路:
KDtree模板題。
參考自http://www.cn
【learning】kd-tree
應該 原因 處理 math 二叉 。。 答案 dal 添加 吐槽
kd-tree這個東西很早就聽說過了但是qwq一直沒有去了解
(原因的話。。啊哈哈聽說是什麽跟二維平面之類的東西有關的所以就慫掉了qwq沒錯就是慫qwq)
但其實好像。。真的很暴力啊qwq知道思路之後隨便亂搞
【BZOJ1941】Hide and Seek(KD-Tree)
hid cstring clu truct amp OS nth href getc 【BZOJ1941】Hide and Seek(KD-Tree)
題面
BZOJ
洛谷
題解
\(KD-Tree\)對於每個點搜一下最近點和最遠點就好了
#include<iostr
kd-tree板子
friend per temp cst return build http com names https://www.lydsy.com/JudgeOnline/problem.php?id=2648
存個kd-tree板子
#include<cstdio&
bryce1010專題訓練——最小費用最大流
bryce1010專題訓練——最小費用最大流
分為:
SPFA費用流
zkw費用流
【最小費用最大流+浮點數】 HDU5988 Coding contest https://vjudge.net/problem/HDU-5988
【題意】 給定n個點,
kd-tree找最鄰近點 Python實現
kd-tree找最鄰近點 Python實現
基本概念
kd-tree是KNN演算法的一種實現。演算法的基本思想是用多維空間中的例項點,將空間劃分為多塊,成二叉樹形結構。劃分超矩形上的例項點是樹的非葉子節點,而每個超矩形內部的例項點是葉子結點。
超矩形劃分方法
有資料集data
BZOJ 2648: SJY擺棋子(kd tree)
題目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int
hdu 4347 The Closest M Points (kd tree 模板題)
題目:http://acm.hdu.edu.cn/showproblem.php?pid=4347
#include<bits/stdc++.h>
using namespace std;
#define sq(x) (x)*(x)
const int maxn=6e4+10;
kd-tree 題目練習
kd tree原理詳解: KD-樹介紹
程式碼模板和部分題借鑑:kd-tree小結
例題一: P4475 巧克力王國
思路:根據巧克力a和可可b建立kd-tree,每個節點維護子樹的最大的a,b以及最小的a,b,一個子樹的權值和sum,每次查詢,如果四對極值點 a b滿足 x*a+