首页 > 代码库 > 【kd-tree】hdu5992 Finding Hotels

【kd-tree】hdu5992 Finding Hotels

比较裸的kd-tree,但是比较考验剪枝。

貌似除了经典的矩形距离剪枝之外,

还必须加个剪枝是某个矩形内的最小价格如果大于价格限制的话,则剪枝。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 200010
#define EPS 0.00000001
#define INF 1000000000000000007.0
#define KD 2
struct data{
	int x,y,v;
	double d;
	int id;
	data(const int &_x,const int &_y,const int &_v,const double &_d,const int &_id){
		x=_x; y=_y; v=_v; d=_d; id=_id;
	}
	data(){}
}ans;
bool operator < (const data &a,const data &b){
	if(fabs(a.d-b.d)>=EPS){
		return a.d-b.d<-EPS;
	}
	return a.id<b.id;
}
int qp[KD],qv;
int n,root;
bool dn;
double sqr(int x)
{
    return (double)x*(double)x;
}
int Abs(int x)
{
    return x<0 ? (-x) : x;
}
struct Node
{
    int minn[KD],maxx[KD],p[KD],v,id,minv;
    int ch[2];
    void Init()
      {
        for(int i=0;i<KD;++i)
          minn[i]=maxx[i]=p[i];
        minv=v;
        ch[0]=ch[1]=0;
      }
    bool CheckIn()
      {
        for(int i=0;i<KD;++i)
          if(!(minn[i]<=qp[i] && qp[i]<=maxx[i]))
            return 0;
        return 1;
      }
    int Dis()
      {
        if(CheckIn()){
        	return 0;
        }
        int res=2147483647;
        res=min(res,Abs(minn[0]-qp[0]));
        res=min(res,Abs(maxx[0]-qp[0]));
        res=min(res,Abs(minn[1]-qp[1]));
        res=min(res,Abs(maxx[1]-qp[1]));
        return res;
      }
}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]);
    		}
    		T[rt].minv=min(T[rt].minv,T[T[rt].ch[i]].minv);
    	}
	}
}
bool operator < (const Node &a,const Node &b)
{
    return a.p[dn]!=b.p[dn] ? a.p[dn]<b.p[dn] : a.p[dn^1]<b.p[dn^1];
}
int Buildtree(int l=1,int r=n,bool 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);
    if(m!=r) T[m].ch[1]=Buildtree(m+1,r,d^1);
    Update(m);
    return m;
}
double Dis(int a[],int b[])
{
    return sqrt(sqr(a[0]-b[0])+sqr(a[1]-b[1]));
}
void Query(int rt=root)
{
	if(T[rt].v<=qv){
		ans=min(ans,data(T[rt].p[0],T[rt].p[1],T[rt].v,Dis(T[rt].p,qp),T[rt].id));
	}
    int 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]=2147483647;
    bool f=(dd[0]<=dd[1]);
    if(T[T[rt].ch[!f]].minv<=qv && (double)dd[!f]-ans.d<(-EPS)) Query(T[rt].ch[!f]);
    if(T[T[rt].ch[f]].minv<=qv && (double)dd[f]-ans.d<(-EPS)) Query(T[rt].ch[f]);
}
int Zu,m;
int main()
{
//	freopen("k.in","r",stdin);
	scanf("%d",&Zu);
	for(int zu=1;zu<=Zu;++zu){
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;++i){
			scanf("%d%d%d",&T[i].p[0],&T[i].p[1],&T[i].v);
			T[i].id=i;
		}
    	root=(1+n>>1);
    	Buildtree();
    	for(int i=1;i<=m;++i){
    		ans.d=INF;
    		scanf("%d%d%d",&qp[0],&qp[1],&qv);
        	Query();
    		printf("%d %d %d\n",ans.x,ans.y,ans.v);
    	}
	}
    return 0;
}

【kd-tree】hdu5992 Finding Hotels