题意:n家旅店,每个旅店都有坐标x,y,每晚价钱z,m个客人,坐标x,y,钱c,问你每个客人最近且能住进去(非花最少钱)的旅店,一样近的选排名靠前的。

思路:KD树模板题

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn = + ;
const int seed = ;
const ll MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
using namespace std; #define lson rt << 1
#define rson rt << 1 | 1
#define Pair pair<ll, Node> int k, idx; //维数k struct Node
{
int feature[]; //定义属性数组
int id;
bool operator < (const Node &u) const
{
return feature[idx] < u.feature[idx];
}
}_data[maxn], p; //_data[]数组代表输入的数据
Node data[ * maxn]; //data[]数组代表K-D树的所有节点数据
int flag[ * maxn]; //用于标记某个节点是否存在,1表示存在,-1表示不存在 priority_queue<Pair> Q; //队列Q用于存放离p最近的m个数据
ll Sqrt(ll a, ll b){ //欧几里得距离平方
return (a - b) * 1LL * (a - b);
} //建树步骤,参数dept代表树的深度
void Build(int l, int r, int rt, int dept)
{
if(l > r) return;
flag[rt] = ; //表示编号为rt的节点存在
flag[lson] = flag[rson] = -; //当前节点的孩子暂时标记不存在
idx = dept % k; //按照编号为idx的属性进行划分
int mid = (l + r) >> ;
nth_element(_data + l, _data + mid, _data + r + ); //nth_element()为STL中的函数 algorithm
data[rt] = _data[mid];
Build(l, mid - , lson, dept + ); //递归左子树
Build(mid + , r, rson, dept + ); //递归右子树
} //查询函数,寻找离p最近的m个特征属性
void Query(Node p, int m, int rt, int dept)
{
if(flag[rt] == -) return; //不存在的节点不遍历
Pair cur(, data[rt]); //获取当前节点的数据和到p的距离
for(int i = ; i < k; i++) //欧几里得距离的平方
cur.first += Sqrt((ll)data[rt].feature[i], (ll)p.feature[i]);
int dim = dept % k; //跟建树一样,这样能保证相同节点的dim值不变
bool fg = ; //用于标记是否需要遍历右子树
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 + ); //如果节点x存在,则进入子树继续遍历 //以下是回溯过程,维护一个优先队列
if(Q.size() < m) //如果队列没有满,则继续放入
{
if(cur.second.feature[] <= p.feature[]) Q.push(cur);
fg = ;
}
else
{
if(cur.first < Q.top().first && cur.second.feature[] <= p.feature[]) //如果找到更小的距离,则用于替换队列Q中最大的距离的数据
{
Q.pop();
Q.push(cur);
}
else if(cur.first == Q.top().first && cur.second.id < Q.top().second.id && cur.second.feature[] <= p.feature[]){
Q.pop();
Q.push(cur);
}
if(Sqrt((ll)p.feature[dim], (ll)data[rt].feature[dim]) < Q.top().first)
{
fg = ;
}
}
if(~flag[y] && fg)
Query(p, m, y, dept + );
}
int main(){
int T, n, m;
k = ;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
for(int i = ; i < n; i++){
for(int j = ; j < ; j++)
scanf("%d", &_data[i].feature[j]);
_data[i].id = i;
}
Build(, n - , , );
while(m--){
while(!Q.empty()) Q.pop();
for(int i = ; i < ; i++)
scanf("%d", &p.feature[i]);
Query(p, , , );
p = Q.top().second;
printf("%d %d %d\n", p.feature[], p.feature[], p.feature[]);
}
}
return ;
}

模板:

#define lson rt << 1
#define rson rt << 1 | 1
#define Pair pair<ll, Node> int k, idx; //维数k struct Node
{
int feature[]; //定义属性数组
int id;
bool operator < (const Node &u) const
{
return feature[idx] < u.feature[idx];
}
}_data[maxn], p; //_data[]数组代表输入的数据
Node data[ * maxn]; //data[]数组代表K-D树的所有节点数据
int flag[ * maxn]; //用于标记某个节点是否存在,1表示存在,-1表示不存在 priority_queue<Pair> Q; //队列Q用于存放离p最近的m个数据
ll Sqrt(ll a, ll b){ //欧几里得距离平方
return (a - b) * 1LL * (a - b);
} //建树步骤,参数dept代表树的深度
void Build(int l, int r, int rt, int dept)
{
if(l > r) return;
flag[rt] = ; //表示编号为rt的节点存在
flag[lson] = flag[rson] = -; //当前节点的孩子暂时标记不存在
idx = dept % k; //按照编号为idx的属性进行划分
int mid = (l + r) >> ;
nth_element(_data + l, _data + mid, _data + r + ); //nth_element()为STL中的函数 algorithm
data[rt] = _data[mid];
Build(l, mid - , lson, dept + ); //递归左子树
Build(mid + , r, rson, dept + ); //递归右子树
} //查询函数,寻找离p最近的m个特征属性
void Query(Node p, int m, int rt, int dept)
{
if(flag[rt] == -) return; //不存在的节点不遍历
Pair cur(, data[rt]); //获取当前节点的数据和到p的距离
for(int i = ; i < k; i++) //欧几里得距离的平方
cur.first += Sqrt((ll)data[rt].feature[i], (ll)p.feature[i]);
int dim = dept % k; //跟建树一样,这样能保证相同节点的dim值不变
bool fg = ; //用于标记是否需要遍历右子树
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 + ); //如果节点x存在,则进入子树继续遍历 if(Q.size() < m) //如果队列没有满,则继续放入
{ //注意,这里必须让fg=1,以后改时注意
Q.push(cur);
fg = ;
}
else
{
if(cur.first < Q.top().first) //如果找到更小的距离,则用于替换队列Q中最大的距离的数据
{
Q.pop();
Q.push(cur);
}
if(Sqrt((ll)p.feature[dim], (ll)data[rt].feature[dim]) < Q.top().first)
{
fg = ;
}
}
if(~flag[y] && fg)
Query(p, m, y, dept + );
}

HDU 5992 Finding Hotels(KD树)题解的更多相关文章

  1. HDU 5809 Ants(KD树+并查集)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5809 [题目大意] 给出一些蚂蚁和他们的巢穴,一开始他们会在自己的巢穴(以二维坐标形式给出),之后 ...

  2. K-D树问题 HDU 4347

    K-D树可以看看这个博客写的真心不错!这里存个版 http://blog.csdn.net/zhjchengfeng5/article/details/7855241 HDU 4349 #includ ...

  3. 2016 ICPC青岛站---k题 Finding Hotels(K-D树)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5992 Problem Description There are N hotels all over ...

  4. 【HDU5992】Finding Hotels 【KD树】

    题意 给出n个酒店的坐标和价格,然后m个查询,每个查询给出一个人的坐标和能承受的最大价格,然后找出在他价格承受范围以内,距离他最近的宾馆,如果有多个,那么输出第一个 分析 kd树的模板题 #inclu ...

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

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

  6. HDU 6022---MG loves set(K-D树)

    题目链接 Problem Description MG is an intelligent boy. One day he was challenged by the famous master ca ...

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

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

  8. 数据结构(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 ...

  9. hdu 2966 In case of failure k-d树

    题目链接 给n个点, 求出每个点到离它最近的点的距离. 直接建k-d树然后查询就可以  感觉十分神奇... 明白了算法原理但是感觉代码还不是很懂... #include <bits/stdc++ ...

随机推荐

  1. KVM--安装及初步使用

    KVM是Kernel-based Virtual Machine的简称,是一个开源的虚拟化模块,今天我将在CentOS7的操作系统上安装KVM,以下是我的安装步骤. 一.环境信息 系统: CentOS ...

  2. CSS表单设计

    今天我们开始学习<十天学会web标准(div+css)>的css表单设计,包含以下内容和知识点: 改变文本框和文本域样式 用图片美化按钮 改变下拉列表样式 用label标签提升用户体验 一 ...

  3. 【Python】关于Python多线程的一篇文章转载

    猪哥推荐的学习网址 http://www.jb51.net/article/110164.htm yeayee ------>更多技巧------>更多源码------>http:/ ...

  4. 统计词语频率保存到xls

    import json import jieba.analyse as anl import xlwt # 获取待统计的文本内容 # 打开文件 f = open('zhilian.json', 'r' ...

  5. windows使用方法

    1:截图搜索英文单词:snipping tool 2: 修改语言,搜索language 3:关闭fn键,按键 fn+esc(fnlock).  就可以将fn关闭和开启.

  6. springmvc返回json数据的工具类

    在ssm框架下,MVC向前端返回数据的json工具类代码如下: public class JsonResult<T> { public static final int SUCCESS=0 ...

  7. [LeetCode] 675. Cut Off Trees for Golf Event_Hard tag: BFS

    You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-nega ...

  8. pod 的warning一定要注意消除,要不然你的pod配置有问题无法导入

    and the CHANGELOG for this version http://git.io/BaH8pQ. Downloading dependencies Using BlocksKit (2 ...

  9. 树结构数据的展示和编辑-zTree树插件的简单使用

    最近在项目当中遇到一个需求,需要以树结构的方式展示一些数据,并可对每一个树节点做内容的编辑以及树节点的添加和删除,刚好听说有zTree这个插件可以实现这样的需求,所以在项目的这个需求完成之后,在博客里 ...

  10. webapi swagger学习笔记

    版权声明:部分摘抄其他博主朋友的博文内容,旨在分享学习,如给您带来不便,请原谅.原文地址 http://www.cnblogs.com/yanweidie/p/5709113.html#_label3 ...