<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 4,  comments - 0,  trackbacks - 0
    寫個kd-tree模板...無它
    UPD: 以前寫的代碼太難看啦,趁去南京賽區之前整理模板重寫了一下...

      1 //hdu4347 KD Tree
      2 //詢問k維空間中距某點最近的m個點
      3 
      4 #include <cstdio>
      5 #include <queue>
      6 #include <algorithm>
      7 
      8 using namespace std;
      9 
     10 const int N = 200010;
     11 const int DIM = 5;
     12 
     13 inline double sqr(double x) { return x*x; }
     14 
     15 int k, n;        //k為維數, n為點數
     16 
     17 struct Point {
     18     int x[DIM];
     19     double cald(Point o) {
     20         double ret = 0;
     21         for (int i = 0; i < k; i++) {
     22             ret += sqr(x[i] - o.x[i]);
     23         }
     24         return ret;
     25     }
     26     void print() {
     27         for (int i = 0; i < k; i++) {
     28             printf("%d", x[i]);
     29             i == k - 1 ? puts("") : printf(" ");
     30         }
     31     }
     32 }point[N];
     33 
     34 struct Heap_t {
     35     Point p; double dis;
     36     Heap_t() {}
     37     Heap_t(Point _p, double _dis) : p(_p), dis(_dis) {}
     38     bool operator < (const Heap_t &o) const {
     39         return dis < o.dis;
     40     }
     41 };
     42 
     43 priority_queue<Heap_t> q;        //維護前m大數
     44 
     45 //笨方法,用于對動態第dim維排序,通過修改全局變量dim來達到目的
     46 int dim;
     47 bool cmp(Point a, Point b) {
     48     return a.x[dim] < b.x[dim];
     49 }
     50 
     51 struct KDTree {
     52     struct Node {
     53         Point p;
     54         int size;
     55     }t[N];
     56     inline int LC(int x) { return x << 1; }
     57     inline int RC(int x) { return x << 1 | 1; }
     58     //建樹,采取wiki上的建樹方法
     59     void build(Point p[], int l, int r, int rt, int dep) {
     60         if (l > r) return;
     61         t[rt].size = r - l;
     62         t[LC(rt)].size = t[RC(rt)].size = -1;
     63         dim = dep % k;
     64         int m = (l + r) >> 1;
     65         nth_element(p + l, p + m, p + r + 1, cmp);
     66         t[rt].p = p[m];
     67         build(p, l, m - 1, LC(rt), dep + 1);
     68         build(p, m + 1, r, RC(rt), dep + 1);
     69     }
     70     void insert(Heap_t h) {
     71         if (h.dis < q.top().dis) {
     72             q.pop(); q.push(h);
     73         }
     74     }
     75     //詢問前m近的點。
     76     //與最近鄰相似,先一路搜到葉子,然后如果當前得到的點數<m時,要搜索所有的子樹。
     77     //得到m個點之后就維護一個大小為m的堆,當前節點距離<堆頂元素距離時,將當前節點加入,堆頂元素彈出。
     78     //其余與最近鄰詢問相似。
     79     void query(Point p, int rt, int dep, int m) {
     80         if (t[rt].size == -1return;
     81         Heap_t h(t[rt].p, t[rt].p.cald(p));
     82         int dim = dep % k;
     83         if (p.x[dim] < t[rt].p.x[dim]) {
     84             query(p, LC(rt), dep + 1, m);
     85             if (q.size() < m) {
     86                 q.push(h);
     87                 query(p, RC(rt), dep + 1, m);
     88             } else {
     89                 insert(h);
     90                 //如果要查詢的點與超平面的距離 < 堆頂元素的距離,則要到另一邊超平面去查詢
     91                 if (sqr(p.x[dim] - t[rt].p.x[dim]) < q.top().dis) {
     92                     query(p, RC(rt), dep + 1, m);
     93                 }
     94             }
     95         } else {
     96             query(p, RC(rt), dep + 1, m);
     97             if (q.size() < m) {
     98                 q.push(h);
     99                 query(p, LC(rt), dep + 1, m);
    100             } else {
    101                 insert(h);
    102                 if (sqr(p.x[dim] - t[rt].p.x[dim]) < q.top().dis) {
    103                     query(p, LC(rt), dep + 1, m);
    104                 }
    105             }
    106         }
    107     }
    108 }kdt;
    109 
    110 int main() {
    111     while (~scanf("%d%d"&n, &k)) {
    112         for (int i = 0; i < n; i++) {
    113             for (int j = 0; j < k; j++) {
    114                 scanf("%d"&point[i].x[j]);
    115             }
    116         }
    117         kdt.build(point, 0, n - 110);
    118         int t; scanf("%d"&t);
    119         for (int i = 0; i < t; i++) {
    120             Point ask;
    121             for (int j = 0; j < k; j++) {
    122                 scanf("%d"&ask.x[j]);
    123             }
    124             int m; scanf("%d"&m);
    125             kdt.query(ask, 10, m);
    126             Point p[10];
    127             for (int j = 0!q.empty(); j++) {
    128                 p[j] = q.top().p; q.pop();
    129             }
    130             printf("the closest %d points are:\n", m);
    131             for (int j = m - 1; j >= 0; j--) {
    132                 p[j].print();
    133             }
    134         }
    135     }
    136     return 0;
    137 }

    允許轉載,轉載請注明出處:
    posted on 2012-08-13 22:35 NKU->lkjslkjdlk 閱讀(672) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2012年8月>
    2930311234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿

    隨筆檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲乱码中文字幕久久孕妇黑人| 女人18毛片特级一级免费视频 | 久9这里精品免费视频| 亚洲午夜激情视频| 一级毛片正片免费视频手机看 | 免费福利电影在线观看| 91麻豆国产自产在线观看亚洲| 污网站在线观看免费| 亚洲精品tv久久久久久久久久| 一级成人a做片免费| 国产亚洲情侣一区二区无| 中文在线观看国语高清免费| 亚洲αv在线精品糸列| 18成禁人视频免费网站| 亚洲午夜成激人情在线影院| 国产卡一卡二卡三免费入口| 亚洲另类无码专区首页| 又大又黄又粗又爽的免费视频 | 中国一级特黄的片子免费| 亚洲综合一区无码精品| 亚洲成AV人在线观看网址| 丁香花在线观看免费观看图片| 亚洲一区二区三区乱码在线欧洲| 日韩精品视频免费在线观看| 免费一级毛suv好看的国产网站 | 免费h视频在线观看| 美女被免费视频网站| 亚洲国产精品福利片在线观看| 16女性下面无遮挡免费| 一区二区三区免费看| 亚洲AⅤ男人的天堂在线观看 | 亚洲日本一线产区和二线产区对比| 亚洲国产精品嫩草影院在线观看| 国产又大又长又粗又硬的免费视频| 亚洲乱码在线视频| 亚洲av无码专区在线播放| 亚洲国产精品成人| 国产精品免费一级在线观看| 成年在线网站免费观看无广告| 2022国内精品免费福利视频| 亚洲欧洲自拍拍偷综合|