首页 > 学院 > 开发设计 > 正文

[模版] K/最近邻匹配(KD Tree)

2019-11-10 18:45:41
字体:
来源:转载
供稿:网友

nth_element相当于快排的split/choose pivot过程

2D 最近

#include <bits/stdc++.h>#define mem(a,b) memset(a,b,sizeof(a))const int INF=0x3f3f3f3f;const int maxn=1e5+50;typedef long long ll;using namespace std;int cmpNo;struct Node{ int x[2],l,r,id; bool Operator <(const Node &b)const{ return x[cmpNo]<b.x[cmpNo]; }};ll calDis(Node &l,Node &r){ ll dx=l.x[0]-r.x[0],dy=l.x[1]-r.x[1]; return dx*dx+dy*dy;}Node p[maxn];int Build(int l,int r,int d){ if(l>r)return 0; cmpNo=d; int mid=l+r>>1; nth_element(p+l,p+mid,p+r+1); p[mid].l=Build(l,mid-1,1-d); p[mid].r=Build(mid+1,r,1-d); return mid;}ll ansDist;int ansId;void Kth(int l,int r,Node &tar,int d){ if(l>r)return; int mid=l+r>>1; if(p[mid].id!=tar.id){ ll tmp=calDis(p[mid],tar); if(tmp<ansDist){ ansDist=tmp; ansId=p[mid].id; } } long long t=tar.x[d]-p[mid].x[d]; if(t<=0){ Kth(l,mid-1,tar,1-d); if(ansDist>t*t) Kth(mid+1,r,tar,1-d); } else{ Kth(mid+1,r,tar,1-d); if(ansDist>t*t) Kth(l,mid-1,tar,1-d); }}Node a[maxn];int main(){ int T; scanf("%d",&T); for(int cs=1;cs<=T;cs++) { int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d %d",&p[i].x[0],&p[i].x[1]); p[i].id=i; a[i]=p[i]; } Build(1,n,0); for(int i=1;i<=n;i++) { ansDist=1e18; Kth(1,n,a[i],0); PRintf("%lld/n",calDis(a[i],a[ansId])); } } return 0;}

K维 Q近

#include <bits/stdc++.h>#define mem(a,b) memset(a,b,sizeof(a))const int INF=0x3f3f3f3f;const int maxn=4e5+50;typedef long long ll;using namespace std;int cmpNo;const int K=2;struct Node{ int x[K],l,r,id; bool operator <(const Node &b)const{ return x[cmpNo]<b.x[cmpNo]; }};long long Dis(const Node &a,const Node &b){ long long ret=0; for(int i=0;i<K;i++) ret+=(a.x[i]-b.x[i])*(a.x[i]-b.x[i]); return ret;}Node p[maxn];int Build(int l,int r,int d){ if(l>r)return 0; cmpNo=d; int mid=l+r>>1; nth_element(p+l,p+mid,p+r+1); p[mid].l=Build(l,mid-1,(d+1)%K); p[mid].r=Build(mid+1,r,(d+1)%K); return mid;}priority_queue<pair<ll,int> >q;void Kth(int l,int r,Node tar,int k,int d){ if(l>r)return; int mid=l+r>>1; if(p[mid].id!=tar.id){ pair<ll,int>v=make_pair(Dis(p[mid],tar),p[mid].id); if(q.size()==k && v<q.top())q.pop(); if(q.size()<k)q.push(v); } ll t=tar.x[d]-p[mid].x[d]; if(t<=0){ Kth(l,mid-1,tar,k,(d+1)%K); if(q.top().first>t*t) Kth(mid+1,r,tar,k,(d+1)%K); } else{ Kth(mid+1,r,tar,k,(d+1)%K); if(q.top().first>t*t) Kth(l,mid-1,tar,k,(d+1)%K); }}Node a[maxn];ll calDis(Node &l,Node &r){ ll dx=l.x[0]-r.x[0],dy=l.x[1]-r.x[1]; return dx*dx+dy*dy;}const int Q=2;int main(){ int T; scanf("%d",&T); for(int cs=1;cs<=T;cs++) { int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d %d",&p[i].x[0],&p[i].x[1]); p[i].id=i; a[i]=p[i]; } Build(1,n,0); for(int i=1;i<=n;i++) { while(!q.empty()) q.pop(); for(int j=0;j<Q;j++) q.push(make_pair(1e18,-1)); Kth(1,n,a[i],Q,0); while(!q.empty()){ printf("%lld/n",calDis(a[i],a[q.top().second])); q.pop(); } } } return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表