HDU 2966 In case of failure (k-d树)
来源:互联网 发布:圆方铺砖王软件锁 编辑:程序博客网 时间:2024/06/06 16:51
题意:给出n个点,找出每个点距离他们最近的点的距离的平方。
思路:k-d树的模板题,先将所有点建立好k-d树,然后在依次求一下距离他们最近的点,如果找到的点是他们自己的时候设为距离为无穷大即可。
///k-d树#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>typedef long long ll;const int maxn = 2 * 1e5 + 10;const ll INF = 3 * 1e18;const double eps = 1e-6;using namespace std;int k, n, nodecnt, t; ///点的维数,个数struct point { ll data[5]; int split; ///分裂维 void input() { for(int i = 0; i < k; i++) scanf("%lld", &data[i]); } bool operator < (point p) const { int i = split; if(data[i] != p.data[i]) return data[i] < p.data[i]; for(int j = 0; j < k; j++) { if(data[j] == p.data[j]) continue; return data[j] < p.data[j]; } return false; }} p[maxn], ot[maxn];struct node { int son[2]; point p; int split; ///分裂维} kd[maxn];///建立k-d树void build(int o, int l, int r) { if(r < l) return ; int nn = r - l + 1, sp; double EX[5], EXX[5]; memset(EX, 0, sizeof EX); ///E(X) memset(EXX, 0, sizeof EXX); ///E(X^2) for(int i = l; i <= r; i++) { for(int j = 0; j < k; j++) { EX[j] += (double)p[i].data[j] / nn; EXX[j] += (double)p[i].data[j] * p[i].data[j] / nn; } } ///D(X) = E(X^2) - E(X)^2,将方差最大的维作为分裂维 double dx = -1; for(int i = 0; i < k; i++) { double d = EXX[i] - EX[i] * EX[i]; if(dx < d) { dx = d; sp = i; } } kd[o].split = sp; for(int i = l; i <= r; i++) { p[i].split = sp; } int mid = (l + r) >> 1; ///sort(p + l, p + r + 1); nth_element (p + l, p + mid, p + r + 1); ///O(n) for(int i = 0; i < k; i++) { kd[o].p.data[i] = p[mid].data[i]; } if(mid - 1 >= l) { nodecnt++; kd[o].son[0] = nodecnt; build(kd[o].son[0], l, mid - 1); } if(mid + 1 <= r) { nodecnt++; kd[o].son[1] = nodecnt; build(kd[o].son[1], mid + 1, r); }}///两点的距离平方ll dis(point a, point b) { ll d = 0; for(int i = 0; i < k; i++) { d += (a.data[i] - b.data[i]) * (a.data[i] - b.data[i]); } return d;}///寻找距离点p最近的点ll mindistance(int o, point po) { if(!o) return INF; int s = 0; ///寻找进入的子树 if(kd[o].p.data[kd[o].split] != po.data[kd[o].split]) { s = kd[o].p.data[kd[o].split] > po.data[kd[o].split] ? 0 : 1; } else { for(int i = 0; i < k; i++) { if(kd[o].p.data[i] == po.data[i]) continue; s = kd[o].p.data[i] > po.data[i] ? 0 : 1; break; } } ///查询点的位置 int nxt = kd[o].son[s]; int other = kd[o].son[s ^ 1]; ll di = dis(kd[o].p, po), dr = 0; if(!di) di = INF; ll dl = mindistance(nxt, po); if(dl) di = min(di, dl); if(!di) di = INF; double g = sqrt(di); ///是否要进入另一棵子树 ll f = s ? -1 : 1; ll lo = kd[o].p.data[kd[o].split]; ///当前节点分裂维的坐标 double lp = po.data[kd[o].split] + f * sqrt(di); if(s == 0 && lp + eps > lo) dr = mindistance(other, po); if(s == 1 && lp - eps < lo) dr = mindistance(other, po); if(di && dr) di = min(di, dr); else if(!di) di = dr; if(!di) di = INF; return di;}int main() { k = 2; scanf("%d", &t); while(t--) { scanf("%d", &n); nodecnt = 1; for(int i = 0; i < maxn; i++) { kd[i].son[0] = kd[i].son[1] = 0; } for(int i = 0; i < n; i++) { p[i].input(); ot[i].data[0] = p[i].data[0]; ot[i].data[1] = p[i].data[1]; } build(1, 0, n - 1); for(int i = 0; i < n; i++) { printf("%lld\n", mindistance(1, ot[i])); } } return 0;}
0 0
- hdu 2966 In case of failure(k-d 树)
- HDU 2966 In case of failure (k-d树)
- K-D tree HDU 2966 In case of failure
- hdu 2966 In case of failure (k-d树 最近邻近点)
- HDU 2966 In case of failure(k-dTree)
- 【HDU】2966 In case of failure【KD树】
- HDU 2966 In case of failure KD树
- HDU 2966 In case of failure 基础KD树
- Hdu 2966 In case of failure kd-tree模板题
- HDU ACM 2966 In case of failure ->K_D树模版题
- kd树 hdu2966 In case of failure
- hdu2966 In case of failure(这道题就和ta的name一样,failure)
- [CF310]D. Case of Fugitive
- codeforces 556 D Case of Fugitive
- #310 (div.2) D. Case of Fugitive
- cf#310-D. Case of Fugitive-贪心
- cf #310 D. Case of Fugitive (二分)
- codeforces 556D Case of Fugitive
- 看我们错过了那么多机会有感
- Java NIO系列教程(二) Channel
- EditText报IndexOutOfBoundsException异常
- 模仿微信拍摄小视频
- servlet学习成果分享
- HDU 2966 In case of failure (k-d树)
- Action_美化下拉框
- Java编程思想 第二章读书笔记
- matlab入门----符号运算
- Java NIO系列教程(三) Buffer
- NYOJ17 单调递增最长子序列
- android Unable to inflate view tag without class attribute
- 去玻璃
- 79. Word Search(unsolved)