zoukankan      html  css  js  c++  java
  • BZOJ1316 树上的询问

    Time Limit: 10 Sec Memory Limit: 162 MB

    Description

    一棵(n)个点的带权有根树,有(p)个询问,每次询问树中是否存在一条长度为(Len)的路径,如果是,输出(Yes)否输出(No).

    Input

    第一行两个整数(n, p)分别表示点的个数和询问的个数. 接下来(n-1)行每行三个数(x, y, c),表示有一条树边(x ightarrow y),长度为(c). 接下来(p)行每行一个数(Len),表示询问树中是否存在一条长度为(Len)的路径.

    Output

    输出有(p)行,YesNo.

    Sample Input

    6 4 
    1 2 5 
    1 3 7 
    1 4 1 
    3 5 2 
    3 6 3 
    1 
    8 
    13 
    14 
    

    Sample Output

    Yes 
    Yes 
    No 
    Yes 
    

    HINT

    (30\%)的数据,(nleq100)
    (100\%)的数据,(nleq10000)(pleq100),长度(leq 1000000)
    做完此题可看下POJ 3237 Tree

    Soultion

    一开始看到这道题就想到点分治,但是发现有那么多不一样的询问,以为要用fft。然后看见边权的域太大,肯定不行。然后又看到数据范围,(pleq100),暴力枚举询问即可。那么这道题就是点分治模板题,不说什么。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<map>
    using namespace std;
    #define lowbit(x) ((x)&(-(x)))
    #define REP(i,a,n) for(register int i=(a);i<=(n);++i)
    #define PER(i,a,n) for(register int i=(a);i>=(n);--i)
    #define FEC(i,x) for(register int i=head[x];i;i=g[i].ne)
    #define dbg(...) fprintf(stderr,__VA_ARGS__)
    namespace io{
    	const int SIZE=(1<<21)+1;char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int f,qr;
    	#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    	inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
    	inline void putc(char x){*oS++=x;if(oS==oT)flush();}
    	template<class I>inline void read(I &x){for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;}
    	template<class I>inline void write(I x){if(!x)putc('0');if(x<0)putc('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)putc(qu[qr--]);}
    	inline void print(const char *s){while(*s!='')putc(*s++);}
    	struct Flusher_{~Flusher_(){flush();}}io_flusher_;
    }//orz laofudasuan
    using io::read;using io::putc;using io::write;using io::print;
    typedef long long ll;typedef unsigned long long ull;
    template<typename A,typename B>inline bool SMAX(A&x,const B&y){return x<y?x=y,1:0;}
    template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;}
    
    const int N=10000+7;
    int n,Q,x,y,z,q[N],rt,sum,mima,num[N],vis[N],dist[N],p[N],hd,tl,f[N],ans[N];map<int,int>s,t;
    struct Edge{int to,ne,w;}g[N<<1];int head[N],tot;
    inline void Addedge(int x,int y,int z){g[++tot].to=y;g[tot].w=z;g[tot].ne=head[x];head[x]=tot;}
    
    inline void Getroot(int x,int fa=0){
    	num[x]=1;int f=0;
    	for(register int i=head[x];i;i=g[i].ne){
    		int y=g[i].to;if(y==fa||vis[y])continue;
    		Getroot(y,x);num[x]+=num[y];SMAX(f,num[y]);
    	}
    	SMAX(f,sum-num[x]);if(SMIN(mima,f))rt=x;
    }
    inline void BFS(int x,int fa){
    	p[hd=0,tl=1]=x;f[x]=fa;
    	while(hd<tl){
    		x=p[++hd];t[dist[x]]++;
    		for(register int i=head[x];i;i=g[i].ne){
    			int y=g[i].to;if(vis[y]||y==f[x])continue;//错误笔记:if中间是||不是&&!!! 
    			dist[y]=dist[x]+g[i].w;p[++tl]=y;f[y]=x;
    		}
    	}
    }
    inline void Calc(int x){
    	s.clear();s[0]=1;
    	for(register int i=head[x];i;i=g[i].ne){
    		int y=g[i].to;if(vis[y])continue;
    		t.clear();dist[y]=g[i].w;BFS(y,x);
    		for(register int j=1;j<=Q;++j)if(!ans[j])
    			for(register int k=1;k<=tl;++k){
    				if(q[j]>=dist[p[k]]&&s.count(q[j]-dist[p[k]])){ans[j]=1;break;}
    			}
    		for(register int i=1;i<=tl;++i)s[dist[p[i]]]++;
    	}
    }
    inline void Solve(int x){
    	vis[x]=1;Calc(x);
    	for(register int i=head[x];i;i=g[i].ne){
    		int y=g[i].to;if(vis[y])continue;
    		mima=sum=num[y];Getroot(y);Solve(rt);
    	}
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("BZOJ1316.in","r",stdin);freopen("BZOJ1316.out","w",stdout);
    #endif
    	read(n),read(Q);for(register int i=1;i<n;++i)read(x),read(y),read(z),Addedge(x,y,z),Addedge(y,x,z);//错误笔记:记得建两条边 
    	for(register int i=1;i<=Q;++i)read(q[i]),q[i]==0?ans[i]=1:0;
    	mima=sum=n;Getroot(1);Solve(rt);
    	for(register int i=1;i<=Q;++i)print(ans[i]?"Yes
    ":"No
    ");
    }
    
  • 相关阅读:
    d
    今天刚注册,测试下
    关于Hadoop的简单介绍
    leveldb 阅读笔记 (2) 简易测试框架
    leveldb 阅读笔记(1) 内存分配器 Arena
    数论
    伴随网站
    convenience website
    大佬独特的骗分技巧
    动态规划
  • 原文地址:https://www.cnblogs.com/hankeke/p/9852256.html
Copyright © 2011-2022 走看看