zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    git忽略.idea文件
    python pip获取所有已安装的第三包
    bootstrap最简单的导航条
    sencha architect开发sencha touch应用注意事项
    反编译sencha toucha打包的apk文件,修改应用名称支持中文以及去除应用标题栏
    TortoiseSVN文件夹及文件图标不显示解决方法
    sql server 约束 查找
    SQLSERVER金额转换成英文大写的函数
    JS把数字金额转换成中文大写数字的函数
    C#中将数字金额转成英文大写金额的函数
  • 原文地址:https://www.cnblogs.com/clrs97/p/4676134.html
Copyright © 2011-2022 走看看