标签:kdt
题解:多维的估价跟二维一样,每一维的贡献跟二维的‘x’、‘y’完全相同。
真不明白不会的是怎么想的,有区别么?!!
细节:
妈蛋的多组数据!调了好久啊、
然后行末还不能有空格,否则PE
除去这些,我是1A。。
可惜没有“除去”这一说。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 50100 #define K 10 #define inf 0x3f3f3f3f using namespace std; int judge,n,m,q; struct Point { int c[K]; bool operator < (const Point &a)const{return c[judge]<a.c[judge];} int d(Point &a) { int ret=0; for(int i=0;i<m;i++)ret+=(c[i]-a.c[i])*(c[i]-a.c[i]); return ret; } }P[N]; struct ANS { int x; Point p; bool operator < (const ANS &a)const {return x<a.x;} }ans[15]; struct KDT { int son[N][2],cnt; Point c[N][2]; void init() { cnt=0; memset(son,0,sizeof(son)); } int newnode(Point &p){cnt++,c[cnt][0]=c[cnt][1]=p;return cnt;} void update(int f) { int i,s; if(son[f][0]) { s=son[f][0]; for(i=0;i<m;i++) c[f][0].c[i]=min(c[f][0].c[i],c[s][0].c[i]), c[f][1].c[i]=max(c[f][1].c[i],c[s][1].c[i]); } if(son[f][1]) { s=son[f][1]; for(i=0;i<m;i++) c[f][0].c[i]=min(c[f][0].c[i],c[s][0].c[i]), c[f][1].c[i]=max(c[f][1].c[i],c[s][1].c[i]); } } int mindis(int f,Point &p) { int ret=0,i; for(i=0;i<m;i++) { if(p.c[i]<c[f][0].c[i])ret+=(c[f][0].c[i]-p.c[i])*(c[f][0].c[i]-p.c[i]); else if(c[f][1].c[i]<p.c[i])ret+=(c[f][1].c[i]-p.c[i])*(c[f][1].c[i]-p.c[i]); } return ret; } int build(int l,int r,int jd=0) { int mid=l+r>>1,i; judge=jd; jd=jd+1>=m?jd-m+1:jd+1; nth_element(P+l,P+mid,P+r+1); int t=0; if(l<mid)t=build(l,mid-1,jd); int x=newnode(P[mid]);son[x][0]=t; if(mid<r)son[x][1]=build(mid+1,r,jd); update(x); return x; } void query(int f,Point &p,int rank) { int Dis[3],i; Dis[2]=P[f].d(p); if(ans[rank-1].x>Dis[2])ans[rank-1].x=Dis[2],ans[rank-1].p=P[f],sort(ans,ans+rank); Dis[0]=Dis[1]=0; if(son[f][0])Dis[0]=mindis(son[f][0],p); if(son[f][1])Dis[1]=mindis(son[f][1],p); int t=Dis[0]>Dis[1]; if(son[f][t]&&Dis[t]<ans[rank-1].x)query(son[f][t],p,rank); t^=1;if(son[f][t]&&Dis[t]<ans[rank-1].x)query(son[f][t],p,rank); } }kdt; int main() { // freopen("test.in","r",stdin); int i,j,k,root; Point x; while(~scanf("%d%d",&n,&m)) { root=0; kdt.init(); for(i=1;i<=n;i++)for(j=0;j<m;j++)scanf("%d",&P[i].c[j]); if(n)root=kdt.build(1,n); for(scanf("%d",&q);q--;) { for(i=0;i<m;i++)scanf("%d",&x.c[i]);scanf("%d",&k); for(i=0;i<15;i++)ans[i].x=inf; kdt.query(root,x,k); printf("the closest %d points are:\n",k); for(i=0;i<k;i++) { for(j=0;j<m-1;j++)printf("%d ",ans[i].p.c[j]); printf("%d\n",ans[i].p.c[m-1]); } } // puts(""); } return 0; }
【BZOJ3053】The Closest M Points KDtree 好模板一只【数组版!!!】
标签:kdt
原文地址:http://blog.csdn.net/vmurder/article/details/42170267