zoukankan      html  css  js  c++  java
  • 【kd-tree】bzoj3053 The Closest M Points

    同p2626。由于K比较小,所以不必用堆。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef double db;
    #define N 50001
    #define INF 2147483647.0
    #define KD 5//ά¶ÈÊý
    int qp[KD];
    int n,root,kd,K;
    int dn;
    struct Ans
    {
        int p[KD];
        db d;
    }ans[10];
    int sqr(const int &x){return x*x;}
    struct Node
    {
        int minn[KD],maxx[KD],p[KD];
        int ch[2];
        void Init()
          {
            for(int i=0;i<kd;++i)
              minn[i]=maxx[i]=p[i];
          }
        db Dis()
          {
            db t=0;
            for(int i=0;i<kd;++i)
              {
                t+=(db)sqr(max(0,minn[i]-qp[i]));
                t+=(db)sqr(max(0,qp[i]-maxx[i]));
              }
            return sqrt(t);
          }
    }T[N<<1];
    void Update(int rt)
    {
        for(int i=0;i<2;++i)
          if(T[rt].ch[i])
            for(int j=0;j<kd;++j)
              {
                T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
                T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
              }
    }
    db Dis(int a[],int b[])
    {
        db t=0;
        for(int i=0;i<kd;++i)
          t+=(db)sqr(a[i]-b[i]);
        return sqrt(t);
    }
    bool operator < (const Node &a,const Node &b){return a.p[dn]<b.p[dn];}
    int Buildtree(int l=1,int r=n,int d=0)
    {
        dn=d;
        int m=(l+r>>1);
        nth_element(T+l,T+m,T+r+1);
        T[m].Init();
        if(l!=m) T[m].ch[0]=Buildtree(l,m-1,(d+1)%kd);
        if(m!=r) T[m].ch[1]=Buildtree(m+1,r,(d+1)%kd);
        Update(m);
        return m;
    }
    void Query(int rt=root)
    {
        db t=Dis(T[rt].p,qp);
        for(int i=0;i<K;++i)
          if(t<ans[i].d)
            {
              for(int j=K-1;j>=i+1;--j)
                ans[j]=ans[j-1];
              ans[i].d=t;
              memcpy(ans[i].p,T[rt].p,sizeof(T[rt].p));
              break;
            }
        db dd[2];
        for(int i=0;i<2;i++)
          if(T[rt].ch[i])
            dd[i]=T[T[rt].ch[i]].Dis();
          else dd[i]=INF;
        bool f=(dd[0]<=dd[1]);
        if(dd[!f]<ans[K-1].d && T[rt].ch[!f]) Query(T[rt].ch[!f]);
        if(dd[f]<ans[K-1].d && T[rt].ch[f]) Query(T[rt].ch[f]);
    }
    int q;
    int main()
    {
    //  freopen("bzoj3053.in","r",stdin);
    //  freopen("bzoj3053.out","w",stdout);
        while(scanf("%d%d",&n,&kd)!=EOF)
          {
            for(int i=1;i<=n;++i)
              for(int j=0;j<kd;++j)
                scanf("%d",&T[i].p[j]);
            Buildtree();
            root=(1+n>>1);
            scanf("%d",&q);
            for(;q;--q)
              {
                for(int i=0;i<kd;++i)
                  scanf("%d",&qp[i]);
                scanf("%d",&K);
                for(int i=0;i<K;++i)
                  ans[i].d=INF;
                Query();
                printf("the closest %d points are:
    ",K);
                for(int i=0;i<K;++i)
                  {
                    for(int j=0;j<kd-1;++j)
                      printf("%d ",ans[i].p[j]);
                    printf("%d
    ",ans[i].p[kd-1]);
                  }
              }
            for(int i=1;i<=n;++i)
              T[i].ch[0]=T[i].ch[1]=0;
          }
        return 0;
    }
  • 相关阅读:
    HDU 1242——Rescue(优先队列)
    [LeetCode] Rectangle Area
    iOS 开发百问(6)
    lucene入门查询索引——(三)
    lucene入门创建索引——(二)
    lucene简介——(一)
    Java基础打包以及批处理命令运行
    Maven从私服上下载所需jar包——(十四)
    Maven部署dao工程到私服上——(十三)
    Maven私服安装及配置——(十二)
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4587130.html
Copyright © 2011-2022 走看看