bzoj 4182
首先很容易看出这是一个树上多重背包问题
设状态$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的更多相关文章
- BZOJ.4182.Shopping(点分治/dsu on tree 树形依赖背包 多重背包 单调队列)
BZOJ 题目的限制即:给定一棵树,只能任选一个连通块然后做背包,且每个点上的物品至少取一个.求花费为\(m\)时最大价值. 令\(f[i][j]\)表示在点\(i\),已用体积为\(j\)的最大价值 ...
- BZOJ 4182 Shopping (点分治+树上多重背包)
题目大意:给你一颗树,你有$m$元钱,每个节点都有一种物品,价值为$w$,代价为$c$,有$d$个,如果在$u$和$v$两个城市都购买了至少一个物品,那么$u,v$路径上每个节点也都必须买至少一个物品 ...
- Week Five
2018.12.25 1.[BZOJ 4310] 2.[BZOJ 3879] 3.[BZOJ 2754] 4.[BZOJ 4698] 5.[Codeforces 914E] 6.[Codeforces ...
- dsu on tree:关于一类无修改询问子树可合并问题
dsu on tree:关于一类无修改询问子树可合并问题 开始学长讲课的时候听懂了但是后来忘掉了....最近又重新学了一遍 所谓\(dsu\ on\ tree\)就是处理本文标题:无修改询问子树可合并 ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
随机推荐
- spring mvc学习 总体概览
spring mvc 设计概览 springmvc处理http请求,主要是在web.xml中配置一个dispatcherservlet,然后由此进行拦截并处理请求返回相应,下面就针对源码大体记 ...
- Mybatis系列(四)映射文件
转自:https://blog.csdn.net/chris_mao/article/details/48811507 Mybatis的真正强大,在于她对SQL的映射,这也是她吸引人的地方.实现相同的 ...
- python之operator模块
python3中已经没有cmp函数,被operator模块代替,在交互模式下使用时,需要导入模块. 在没有导入模块情况下,会出现 提示找不到cmp函数了,那么在python3中该如何使用这个函数呢? ...
- 非常详细的ok6410的linux系统移植…
目录 Linux 3.3.5系统移植 2 LED驱动移植 8 按键驱动移植 9 LCD驱动移植 11 DM9000网卡驱动移植 14 搭建NFS网络文件系统 25 移植触摸屏驱动 38 移植Qt4.8 ...
- NODEJS网站
nodejs https://nodejs.org/en/ nodejs官网 http://nodeapi.ucdok.com/#/api/ nodejs手册 https://www.npmjs.co ...
- 设置窗口的z-order总是在最底部
想让窗口置顶,很简单,只需要在SetWindowPos中指定 HWND_TOPMOST就OK了, 但是如果想要窗口始终位于最底端,Windows却没有提供接口. 不过呢,Windows提供了一个消息W ...
- SpringBoot15 sell02 订单模块
1 订单模块 1.1 MySQL数据表 订单模块涉及到两个数据表: 订单表:主要存储订单相关的基本信息 DROP TABLE IF EXISTS `order_master`; CREATE TABL ...
- Linux文件系统操作命令
Linux文件系统操作命令 文件系统操作命令: 1. cat:可以显示文件的内容(经常和more搭配使用),或将多个文件合并成一个文件. 2. chgrp:用来改变文件或目录所属的用户组,命令的参数以 ...
- sql注意事项积累
1.一定要记住,SQL 对大小写不敏感! 2.sql中的单引号 '',如果单引号中是字符串,代表是常量 如,select 'b.phoneNumeber' from test; 如果是数字,如'123 ...
- JavaScript跨域调用基于JSON的RESTful API
1. 基本术语 AJAX(Asynchronous JavaScript And XML,异步JavaScript和XML):AJAX是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交 ...