zoukankan      html  css  js  c++  java
  • 点分治食用

    洛谷日报
    点分治1

    将块想象为树枝,由高级点向低级点分子树,最后分成n个点,暴力求解

    • Get_rt
      找到当前分治树的重心
      use[v]=>防止从更优级分治的点(祖先)的越界
    
    inline void Get_rt(int x,int fa)
    {
    	f[x]=0;size[x]=1;
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v]||v==fa)continue;
    		
    		Get_rt(v,x);
    		size[x]+=size[v];
    		f[x]=max(f[x],size[v]);
    	}
    	f[x]=max(f[x],SIZE-size[x]);
    	if(f[x]<f[rt])rt=x;
    }
    
    
    • Dfs:分治
      pc[0]=1;可能有边权为0的点
      cala:计算当前分治结果
    inline void dfs(int x)
    {
    	use[x]=1;pc[0]=1;
    	cala(x);
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v])continue;
    		f[rt=0]=n;SIZE=size[v];
    		Get_rt(v,x);
    		dfs(rt);
    	}
    }
    
    • Cala
    inline void cala(int x)
    {
    	int p=0;
    	int c[maxn];//记录当前分治下存在路径情况
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v])continue;
    		cnt[0]=0;//统计路个数
    		//cnt:统计路径长度
    		dis[v]=e[i].val;
    		//分治初始路径长度
    		Get_dis(v,x);
    		//得到路径长度
    		
    		for(int j=1;j<=cnt[0];++j)
    		for(int k=1;k<=m;++k)
    			if(q[k]>=cnt[j])ans[k]|=pc[q[k]-cnt[j]];
    			//与答案匹配
    		
    		for(int j=1;j<=cnt[0];++j)
    		 c[++p]=cnt[j],pc[cnt[j]]=1;
    		 //分治点内打标记
    	}
    	
    	inc(i,1,p)pc[c[i]]=0;
    	//还原,为了下次使用 
    }
    
    • Get_dis
      累加求长度
    inline void Get_dis(int x,int fa)
    {
    	cnt[++cnt[0]]=dis[x];
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v]||v==fa)continue;
    		dis[v]=dis[x]+e[i].val;
    		Get_dis(v,x);
    	}
    }
    

    完整代码

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    const int maxn=1e5+5,maxm=305;
    
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
    	char c;bool f=0;
    	while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    	x=c^48;
    	while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    	if(f)x=-x; 
    } 
    
    int size[maxn],n,m,dis[maxn],rt,SIZE,hd[maxn],f[maxn],pc[maxn];
    int k,cnt[maxn],q[maxn],use[maxn],ans[maxn];
    struct node{
    	int to,nt,val;
    }e[maxn<<1];
    
    inline void add(int x,int y,int z)
    {
    	e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].val=z;
    	e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].val=z;
    }
    
    inline void Get_rt(int x,int fa)
    {
    	f[x]=0;size[x]=1;
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v]||v==fa)continue;
    		
    		Get_rt(v,x);
    		size[x]+=size[v];
    		f[x]=max(f[x],size[v]);
    	}
    	f[x]=max(f[x],SIZE-size[x]);
    	if(f[x]<f[rt])rt=x;
    }
    
    inline void Get_dis(int x,int fa)
    {
    	cnt[++cnt[0]]=dis[x];
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v]||v==fa)continue;
    		dis[v]=dis[x]+e[i].val;
    		Get_dis(v,x);
    	}
    }
    
    inline void cala(int x)
    {
    	int p=0;
    	int c[maxn];
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v])continue;
    		cnt[0]=0;dis[v]=e[i].val;
    		Get_dis(v,x);
    		
    		for(int j=1;j<=cnt[0];++j)
    		for(int k=1;k<=m;++k)
    			if(q[k]>=cnt[j])ans[k]|=pc[q[k]-cnt[j]];
    		
    		for(int j=1;j<=cnt[0];++j)
    		 c[++p]=cnt[j],pc[cnt[j]]=1;
    	}
    	
    	inc(i,1,p)pc[c[i]]=0; 
    }
    
    inline void dfs(int x)
    {
    	use[x]=1;pc[0]=1;
    	cala(x);
    	for(int i=hd[x];i;i=e[i].nt)
    	{
    		int v=e[i].to;
    		if(use[v])continue;
    		f[rt=0]=n;SIZE=size[v];
    		Get_rt(v,x);
    		dfs(rt);
    	}
    }
    
    int main()
    {
    	freopen("in.txt","r",stdin);
    	
    	int x,y,z;
    	rd(n),rd(m);
    	inc(i,2,n)
    	{
    		rd(x),rd(y),rd(z);
    		add(x,y,z); 
    	}
    	inc(i,1,m)rd(q[i]);
    	
    	f[rt]=SIZE=n;
    	Get_rt(1,0);
    	
    	dfs(rt);
    	
    	inc(i,1,m)
    	if(ans[i])
    	   printf("AYE
    ");
    	else printf("NAY
    ");
    	re 0;
    } 
    
  • 相关阅读:
    Codeforces
    BZOJ
    BZOJ
    HDU
    Codeforces
    codeforces
    HDU-5441 Travel 离线-并查集
    codefoeces-1000E We Need More Bosses(tarjan+最长链)
    牛客网暑期ACM多校训练营(第五场)H-subseq 树状数组
    HDU-3533 Escape (BFS
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11287638.html
Copyright © 2011-2022 走看看