首先很容易看出这是一个树上多重背包问题

设状态$f[i][j]$表示以$i$为根的子树中利用的体积是$j$

但是题目中有要求:选择的点集必须是一个联通块

这要怎么处理?

点分治!

首先我们利用点分治的思想,每次拎起一个根节点进行处理,要求这个根节点必选,然后在子树内进行dp

为了保证根节点必选(至少选一个),所以我们在初值时按根节点先选一个处理,也就是在最大合法体积上先去掉一个根节点的体积,然后进行dfs更新,对于子树中每个点同理。

多重背包用二进制优化

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int inf=0x3f3f3f3f;
struct Edge
{
int next;
int to;
}edge[];
int head[];
int w[];
int v[];
int d[];
int maxp[];
int siz[];
int f[][];
bool vis[];
int s,rt;
int cnt=;
int ans=;
int n,m;
int T;
void init()
{
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
memset(f,,sizeof(f));
ans=;
cnt=;
}
void add(int l,int r)
{
edge[cnt].next=head[l];
edge[cnt].to=r;
head[l]=cnt++;
}
void get_rt(int x,int fx)
{
siz[x]=,maxp[x]=;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fx||vis[to])continue;
get_rt(to,x);
siz[x]+=siz[to],maxp[x]=max(maxp[x],siz[to]);
}
maxp[x]=max(maxp[x],s-siz[x]);
if(maxp[x]<maxp[rt])rt=x;
}
void dfs(int x,int fx,int lim)
{
if(lim<=)return;
int j=d[x];
for(int i=;i<j;j-=i,i<<=)
{
for(int k=lim;k>=i*v[x];k--)f[x][k]=max(f[x][k],f[x][k-i*v[x]]+i*w[x]);
}
for(int k=lim;k>=j*v[x];k--)f[x][k]=max(f[x][k],f[x][k-j*v[x]]+j*w[x]);
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to]||to==fx)continue;
for(int j=;j<=lim-v[to];j++)f[to][j]=f[x][j]+w[to];
dfs(to,x,lim-v[to]);
for(int j=;j<=lim-v[to];j++)f[x][j+v[to]]=max(f[x][j+v[to]],f[to][j]);
}
}
void solve(int x)
{
vis[x]=;
for(int i=;i<=m-v[x];i++)f[x][i]=w[x];
dfs(x,,m-v[x]);
for(int i=;i<=m-v[x];i++)ans=max(ans,f[x][i]);
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
rt=,s=siz[to],maxp[rt]=inf;
get_rt(to,);
solve(rt);
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<=n;i++)scanf("%d",&w[i]);
for(int i=;i<=n;i++)scanf("%d",&v[i]);
for(int i=;i<=n;i++)scanf("%d",&d[i]),d[i]--;
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
rt=;
maxp[rt]=s=n;
get_rt(,);
solve(rt);
printf("%d\n",ans);
}
return ;
}

bzoj 4182的更多相关文章

  1. BZOJ.4182.Shopping(点分治/dsu on tree 树形依赖背包 多重背包 单调队列)

    BZOJ 题目的限制即:给定一棵树,只能任选一个连通块然后做背包,且每个点上的物品至少取一个.求花费为\(m\)时最大价值. 令\(f[i][j]\)表示在点\(i\),已用体积为\(j\)的最大价值 ...

  2. BZOJ 4182 Shopping (点分治+树上多重背包)

    题目大意:给你一颗树,你有$m$元钱,每个节点都有一种物品,价值为$w$,代价为$c$,有$d$个,如果在$u$和$v$两个城市都购买了至少一个物品,那么$u,v$路径上每个节点也都必须买至少一个物品 ...

  3. Week Five

    2018.12.25 1.[BZOJ 4310] 2.[BZOJ 3879] 3.[BZOJ 2754] 4.[BZOJ 4698] 5.[Codeforces 914E] 6.[Codeforces ...

  4. dsu on tree:关于一类无修改询问子树可合并问题

    dsu on tree:关于一类无修改询问子树可合并问题 开始学长讲课的时候听懂了但是后来忘掉了....最近又重新学了一遍 所谓\(dsu\ on\ tree\)就是处理本文标题:无修改询问子树可合并 ...

  5. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  6. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  7. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  8. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  9. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

随机推荐

  1. 给安卓端调用的apk、图片下载接口

    package com.js.ai.modules.pointwall.action; import java.io.File; import java.io.FileInputStream; imp ...

  2. js实现的点击div区域外隐藏div区域

    首先看下JS的事件模型,JS事件模型为向上冒泡,如onclick事件在某一DOM元素被触发后,事件将跟随节点向上传播,直到有click事件绑定在某一父节点上,如果没有将直至文档的根. 阻止冒泡:1.对 ...

  3. spark集群配置以及java操作spark小demo

    spark 安装 配置 使用java来操作spark spark 安装 tar -zxvf spark-2.4.0-bin-hadoop2.7.tgz rm spark-2.4.0-bin-hadoo ...

  4. Python特殊语法:filter、map、reduce、lambda

    filter(function, sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决 ...

  5. 用sysbench压测MySQL,通过orzdba监控MySQL

    1.1 安装sysbench wget https://codeload.github.com/akopytov/sysbench/zip/0.5 unzip 0.5 cd sysbench-0.5/ ...

  6. Java中long和Long的区别

    Java的数据类型分两种: 1.基本类型:long,int,byte,float,double,char,short,boolean 2. 对象类型(类): Long,Integer,Byte,Flo ...

  7. Django中间件CsrfViewMiddleware源码分析

    Django Documentation csrf保护基于以下: 1, 一个CSRF cookie基于一个随机生成的值,其他网站无法得到,次cookie有CsrfViewMiddleware产生.它与 ...

  8. Linux vi的基本操作

    进入命令 vi <文件名> 如 vi test 如果test文件存在,则直接打开编辑.如果不存在,则新建一个test的文件,这个新建的文件如果不保存的话,退出编辑器后也不会保存到硬盘中. ...

  9. 17-取石子-hdu1846(巴什博奕)

    http://acm.hdu.edu.cn/showproblem.php?pid=1846 Brave Game Time Limit: 1000/1000 MS (Java/Others)     ...

  10. Docker学习笔记_下载镜像更换为国内源,实现快速下载image

    1.编辑/etc/docker/daemon.json,增加下面内容: { "registry-mirrors": ["https://registry.docker-c ...