Dotted rule edible

Luo Valley Daily
dotted rule 1

  • Get_rt
    find the center of gravity of the current partition tree
    use [v] => more preferably prevented from point fraction rule (ancestor) is out of range

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: Partition
    pc [0] = 1; the right side may have a point of 0
    cala: calculation result of the current partition
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
    accumulated seek length
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);
    }
}

The complete code

#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\n");
    else printf("NAY\n");
    re 0;
} 

Guess you like

Origin www.cnblogs.com/lsyyy/p/11287638.html