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:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
随机推荐
- Py修行路 python基础 (十六)面向对象编程的 继承 多态与多态性 封装
一.继承顺序: 多继承情况下,有两种方式:深度优先和广度优先 1.py3/py2 新式类的继承:在查找属性时遵循:广度优先 继承顺序是多条分支,按照从左往右的顺序,进行一步一步查找,一个分支走完会走另 ...
- in not in 和 null , in 判断范围中可以包含null,而not in判断不能包括null
oracle中,任何字符串与null比较得到的结果都是null,而 oracle的判断条件为null时就退出判断(?) 因此判断某个字符串是否在一个集合中时,not in 和 in的结果完全不一样,如 ...
- Delphi Help
http://docwiki.embarcadero.com/CodeExamples/Seattle/en/Category:Content_by_Version
- 关于苹果safari浏览器登陆时Cookie无法保存的问题
前段时间,修改了登录处理后给到客户端浏览器Cookie的内容,新增了一个姓名的value,发现safari不能保存该Cookie的内容,同时Chrome.firefox.ie等浏览器都能正常的访问,直 ...
- linux启动优化:mdev -s自从…
转载请说明出处:http://control.blog.sina.com.cn/admin/article/article_add.php 近期工作中遇到的问题如下: linux启动后加载根文件系统时 ...
- Cfree clion windows c语言 socket 网络编程
server.c #include <stdio.h> #include <winsock2.h> #define SERVER_PORT 5208 //侦听端口 int ma ...
- 201671010140. 2016-2017-2 《Java程序设计》java学习第三周
java学习第三周 不知不觉,学习java已经是第三周了,不同于初见时的无措,慌张,在接触一段时日后,渐渐熟悉了一些,了解到了它的便利之处,也体会到了它的一些难点,本周主攻第四章,< ...
- codeforce469DIV2——C. Zebras
题意 0, 010, 01010 这一类的01交替且开头和结尾都为0的序列被称为zebra序列.给出一段01序列,尝试能否把他分为k个子序列使得每个子序列都是zebra序列. 分析 这个题应该算是水题 ...
- SSH隧道技术简介
本文的受众如果你遇到了以下问题,那么你应该阅读这篇文章 我听说过这种技术,我对它很感兴趣 我想在家里访问我在公司的机器(写程序,查数据,下电影). 公司为了防止我们用XX软件封锁了它的端口或者服务器地 ...
- JSP页面使用EL表达式出现的问题:javax.el.PropertyNotFoundException: Property 'ID' not found on type java.lang.Str
问题描述: 1. 后台返回到JSP前台的的list,在jsp页面使用EL表达式遍历时出现如下问题:javax.el.PropertyNotFoundException: Property 'ID' n ...