<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
    寫個(gè)kd-tree模板...無它
    UPD: 以前寫的代碼太難看啦,趁去南京賽區(qū)之前整理模板重寫了一下...

      1 //hdu4347 KD Tree
      2 //詢問k維空間中距某點(diǎn)最近的m個(gè)點(diǎn)
      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為維數(shù), n為點(diǎn)數(shù)
     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;        //維護(hù)前m大數(shù)
     44 
     45 //笨方法,用于對動(dòng)態(tài)第dim維排序,通過修改全局變量dim來達(dá)到目的
     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近的點(diǎn)。
     76     //與最近鄰相似,先一路搜到葉子,然后如果當(dāng)前得到的點(diǎn)數(shù)<m時(shí),要搜索所有的子樹。
     77     //得到m個(gè)點(diǎn)之后就維護(hù)一個(gè)大小為m的堆,當(dāng)前節(jié)點(diǎn)距離<堆頂元素距離時(shí),將當(dāng)前節(jié)點(diǎn)加入,堆頂元素彈出。
     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                 //如果要查詢的點(diǎn)與超平面的距離 < 堆頂元素的距離,則要到另一邊超平面去查詢
     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 }

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

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


    網(wǎng)站導(dǎo)航:
     
    <2012年8月>
    2930311234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿

    隨筆檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 欧亚精品一区三区免费| 四虎国产精品永免费| 久久久WWW免费人成精品| 中文字幕av无码无卡免费| 在线观看亚洲精品国产| 亚洲av综合日韩| 少妇高潮太爽了在线观看免费| 久久精品亚洲综合| 一本一道dvd在线观看免费视频| 成年女人毛片免费播放视频m| 中文字幕亚洲精品| 在线成人爽a毛片免费软件| 亚洲丁香色婷婷综合欲色啪| 色www永久免费网站| 亚洲国产成人久久精品99 | 日韩亚洲人成在线综合| 四虎在线免费播放| 成人a毛片免费视频观看| 亚洲国产天堂久久久久久| 老司机福利在线免费观看| 日韩激情淫片免费看| 羞羞视频网站免费入口| 免费A级毛片无码A| 成人无码区免费A∨直播| 亚洲伦另类中文字幕| 久视频精品免费观看99| 亚洲性无码AV中文字幕| 亚洲精品岛国片在线观看| 99免费在线视频| 亚洲日产2021三区| 日本免费电影一区| 国产精品内射视频免费| 午夜亚洲AV日韩AV无码大全| 国产1024精品视频专区免费| 处破女第一次亚洲18分钟| 久久久久亚洲AV无码专区首| 麻豆一区二区免费播放网站| 羞羞漫画登录页面免费| 亚洲黄网站wwwwww| 亚洲国产主播精品极品网红| 一区二区在线免费观看|