• BZOJ4182 : Shopping


    最后选择的一定是树上的一个连通块,考虑树分治,每次只需考虑重心必选的情况,这就变成了以重心为根的树形依赖多重背包问题。

    设f[x][j]表示从根节点到x这条路径及其左边的所有节点,以及以x为根的子树的所有节点中,容量为j的背包选取物品所能得到的最大价值。

    对于x的儿子y,将f[y]初始值设为f[x]中强制放入一个y,然后将d[y]-1二进制拆分后放入f[y]中,最后将f[x][j]与f[y][j]取个最优解即可。

    时间复杂度$O(nmlog nlog d)$。

    #include<cstdio>
    #define N 510
    int T,n,m,i,x,y,ed,g[N],nxt[N<<1],v[N<<1],ok[N<<1],son[N],f[N],size,now;
    int a[N],b[N],c[N],dp[N][4010],ans;
    inline void add(int x,int y){v[++ed]=y,nxt[ed]=g[x],ok[ed]=1,g[x]=ed;}
    inline void up(int&a,int b){if(a<b)a=b;}
    void findroot(int x,int y){
      son[x]=1;f[x]=0;
      for(int i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=y){
        findroot(v[i],x);
        son[x]+=son[v[i]];
        if(son[v[i]]>f[x])f[x]=son[v[i]];
      }
      if(size-son[x]>f[x])f[x]=size-son[x];
      if(f[x]<f[now])now=x;
    }
    void dfs(int x,int y,int m){
      if(m<=0)return;
      int i,j,k,V,W;
      for(j=c[x],i=0;j;i++)if((1<<i)<=j){
        for(V=a[x]<<i,W=b[x]<<i,k=m;k>=W;k--)up(dp[x][k],dp[x][k-W]+V);
        j-=1<<i;
      }else{
        for(V=a[x]*j,W=b[x]*j,k=m;k>=W;k--)up(dp[x][k],dp[x][k-W]+V);
        break;
      }
      for(i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=y){
        for(j=0;j<=m-b[v[i]];j++)dp[v[i]][j]=dp[x][j]+a[v[i]];
        dfs(v[i],x,m-b[v[i]]);
        for(j=b[v[i]];j<=m;j++)up(dp[x][j],dp[v[i]][j-b[v[i]]]);
      }
    }
    void solve(int x){
      int i;
      for(i=0;i<=m-b[x];i++)dp[x][i]=a[x];
      for(dfs(x,i=0,m-b[x]);i<=m-b[x];i++)up(ans,dp[x][i]);
      for(i=g[x];i;i=nxt[i])if(ok[i])ok[i^1]=0,f[0]=size=son[v[i]],findroot(v[i],now=0),solve(now);
    }
    int main(){
      for(scanf("%d",&T);T--;printf("%d
    ",ans)){
        scanf("%d%d",&n,&m),ans=0,ed=1;
        for(i=1;i<=n;i++)scanf("%d",&a[i]),g[i]=0;
        for(i=1;i<=n;i++)scanf("%d",&b[i]);
        for(i=1;i<=n;i++)scanf("%d",&c[i]),c[i]--;
        for(i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
        f[0]=size=n,findroot(1,now=0),solve(now);
      }
      return 0;
    }
    

      

  • 相关阅读:
    加入创业公司有什么利弊
    Find Minimum in Rotated Sorted Array II
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Find Minimum in Rotated Sorted Array
    Remove Duplicates from Sorted Array
    Spiral Matrix
    Spiral Matrix II
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/clrs97/p/4676134.html
Copyright © 2020-2023  润新知