• 【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
    ",ans.x,ans.y,ans.v);
        	}
    	}
        return 0;
    }
  • 相关阅读:
    关于《函数调用关键字》记忆恢复本
    进程一
    PE工具实现
    PE工具界面一
    PE各种操作
    汇编指令repne scas byte ptr es:[edi]
    Dialog
    按钮
    点和线的绘制一
    滚动条二
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6683116.html
Copyright © 2020-2023  润新知