hdu 4347 The Closest M Points (kd tree 模板題)
阿新 • • 發佈:2018-11-22
題目:http://acm.hdu.edu.cn/showproblem.php?pid=4347
#include<bits/stdc++.h> using namespace std; #define sq(x) (x)*(x) const int maxn=6e4+10; int idx,n,k,m,lson[maxn],rson[maxn],tol; struct node { int x[5]; bool operator<(const node &u) const { return x[idx]<u.x[idx]; } }P[maxn]; typedef pair<double,node> PDN; priority_queue<PDN> que; struct KD_tree { node p[maxn<<2]; int build(int l,int r,int dep) { if(l>r) return 0; int rt=++tol; int mid=(l+r)/2; idx=dep%k; nth_element(P+l,P+mid,P+r+1); p[rt]=P[mid]; lson[rt]=build(l,mid-1,dep+1); rson[rt]=build(mid+1,r,dep+1); return rt; } void query(int rt,int m,int dep,node a) { if(rt==0) return; PDN tmp=PDN(0,p[rt]); for(int i=0;i<k;i++) tmp.first+=sq(p[rt].x[i]-a.x[i]); int lc=lson[rt],rc=rson[rt],dim=dep%k,flag=0; if(a.x[dim]>=p[rt].x[dim]) swap(lc,rc); if(lc) query(lc,m,dep+1,a); if(que.size()<m) que.push(tmp),flag=1; else { if(tmp.first<que.top().first)que.pop(),que.push(tmp); if(sq(p[rt].x[dim]-a.x[dim])<que.top().first) flag=1; } if(rc&&flag) query(rc,m,dep+1,a); } }KDT; int main() { while(~scanf("%d%d",&n,&k)) { tol=0; for(int i=0;i<n;i++) for(int j=0;j<k;j++) scanf("%d",&P[i].x[j]); int root=KDT.build(0,n-1,0); int Q;scanf("%d",&Q); while(Q--) { node now; for(int i=0;i<k;i++) scanf("%d",&now.x[i]); scanf("%d",&m); KDT.query(root,m,0,now); node ans[12];int len=0; while(!que.empty()) { ans[++len]=que.top().second; que.pop(); } printf("the closest %d points are:\n",len); for(int i=m;i>=1;i--) for(int j=0;j<k;j++) printf("%d%c",ans[i].x[j],j==k-1?'\n':' '); } } return 0; }