Description

马上就是小苗的生日了,为了给小苗准备礼物,小葱兴冲冲地来到了商店街。商店街有n个商店,并且它们之间的道路构成了一颗树的形状。

第i个商店只卖第i种物品,小苗对于这种物品的喜爱度是wi,物品的价格为ci,物品的库存是di。但是商店街有一项奇怪的规定:如果在商店u,v买了东西,并且有一个商店w在u到v的路径上,那么必须要在商店w买东西。小葱身上有m元钱,他想要尽量让小苗开心,所以他希望最大化小苗对买
到物品的喜爱度之和。这种小问题对于小葱来说当然不在话下,但是他的身边没有电脑,于是他打电话给同为OI选手的你,你能帮帮他吗?

Input

输入第一行一个正整数T,表示测试数据组数。

对于每组数据,
第一行两个正整数n;m;
第二行n个非负整数w1,w2...wn;
第三行n个正整数c1,c2...cn;
第四行n个正整数d1,d2...dn;
接下来n-1行每行两个正整数u;v表示u和v之间有一条道路

Output

输出共T 行,每行一个整数,表示最大的喜爱度之和。

Sample Input

1
3 2
1 2 3
1 1 1
1 2 1
1 2
1 3

Sample Output

4

解题思路:

可以发现答案最后是一颗子树,所以我们只需要枚举子树就好了,由于根节点不定,所以靠点分治来实现枚举根(如果答案比一个子树大,那么一点会经过这个根),Dfs序跑出来做树形背包就好了。

多重背包二进制拆分一下就好了。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
const int N=;
const int M=;
struct pnt{
int hd;
int wgt;
int w;
int c;
int d;
int ind;
int oud;
bool vis;
}p[N],stp;
struct ent{
int twd;
int lst;
}e[N<<];
int T,n,m;
int cnt;
int dfn;
int size;
int root;
int maxsize;
lnt ans;
int lin[N];
lnt dp[N][M];
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void grc_dfs(int x,int f)
{
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f||p[to].vis)
continue;
grc_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
maxs=p[to].wgt;
}
maxs=std::max(maxs,size-p[x].wgt);
if(maxs<maxsize)
{
root=x;
maxsize=maxs;
}
return ;
}
void Build_dfs(int x,int f)
{
lin[++dfn]=x;
p[x].ind=dfn;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f||p[to].vis)
continue;
Build_dfs(to,x);
}
p[x].oud=dfn;
return ;
}
void bin_dfs(int x)
{
p[x].vis=true;
dfn=;
Build_dfs(x,x);
for(int i=;i<=dfn+;i++)
for(int j=;j<=m;j++)
dp[i][j]=;
for(int i=dfn;i;i--)
{
int t=lin[i];
int w=p[t].d-;
for(int j=m;j>=p[t].c;j--)
dp[i][j]=dp[i+][j-p[t].c]+p[t].w;
for(int j=;;j<<=)
{
if(w<j)
j=w;
for(int k=m;k>=j*p[t].c;k--)
dp[i][k]=std::max(dp[i][k],dp[i][k-j*p[t].c]+j*p[t].w);
w-=j;
if(!w)
break;
}
for(int j=;j<=m;j++)
dp[i][j]=std::max(dp[i][j],dp[p[t].oud+][j]);
}
ans=std::max(ans,dp[][m]);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].vis)
continue;
root=;
size=p[to].wgt;
maxsize=0x3f3f3f3f;
grc_dfs(to,to);
bin_dfs(root);
}
return ;
}
int main()
{
//freopen("a.in","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
p[i]=stp;
cnt=,ans=;
for(int i=;i<=n;i++)
scanf("%d",&p[i].w);
for(int i=;i<=n;i++)
scanf("%d",&p[i].c);
for(int i=;i<=n;i++)
scanf("%d",&p[i].d);
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ade(a,b);
ade(b,a);
}
root=;
size=n;
maxsize=0x3f3f3f3f;
grc_dfs(,);
bin_dfs(root);
printf("%lld\n",ans);
}
return ;
}

BZOJ4182: Shopping(点分治,树上背包)的更多相关文章

  1. [BZOJ4182]Shopping (点分治+树上多重背包+单调队列优化)

    [BZOJ4182]Shopping (点分治+树上多重背包+单调队列优化) 题面 马上就是小苗的生日了,为了给小苗准备礼物,小葱兴冲冲地来到了商店街.商店街有n个商店,并且它们之间的道路构成了一颗树 ...

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

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

  3. bzoj4182 Shopping 点分治+单调队列优化多重背包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4182 题解 有一个很直观的想法是设 \(dp[x][i]\) 表示在以 \(x\) 为根的子树 ...

  4. HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)

    题目链接  2017 CCPC Hangzhou  Problem E 题意  给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...

  5. Hdu 6268 点分治 树上背包 bitset 优化

    给你一颗大小为n(3000)的树,树上每个点有点权(100000),再给你一个数m(100000) i为1~m,问树中是否存在一个子图,使得权值为i. 每次solve到一个节点 用一个bitset维护 ...

  6. bzoj4182/luoguP6326 Shopping(点分治,树上背包)

    bzoj4182/luoguP6326 Shopping(点分治,树上背包) bzoj它爆炸了. luogu 题解时间 如果直接暴力背包,转移复杂度是 $ m^{2} $ . 考虑改成点分治. 那么问 ...

  7. HDU4044 GeoDefense(有点不一样的树上背包)

    题目大概说一棵n个结点的树,每个结点都可以安装某一规格的一个塔,塔有价格和能量两个属性.现在一个敌人从1点出发但不知道他会怎么走,如果他经过一个结点的塔那他就会被塔攻击失去塔能量的HP,如果HP小于等 ...

  8. luogu 2014 选课 树上背包

    树上背包 #include<bits/stdc++.h> using namespace std; ; const int inf=0x3f3f3f3f; vector<int> ...

  9. Crazy Shopping(拓扑排序+完全背包)

    Crazy Shopping(拓扑排序+完全背包) Because of the 90th anniversary of the Coherent & Cute Patchouli (C.C. ...

随机推荐

  1. [Teamcenter 2007 开发实战] 调用web service

    前言 在TC的服务端开发中, 能够使用gsoap 来调用web service. 怎样使用 gsoap  , 參考 gsoap 实现 C/C++ 调用web service 接下来介绍怎样在TC中进行 ...

  2. 用motion实现家庭视频监控

    需求?当然不是为了艳照.你们这些猥琐的人类! 毕竟家里总会有没人的时候,出门走到半路忘记煤气灶是不是关了,还得回去看看. 在这个科技以人为本的时代,当然应该是拿出智能手机联网看看啦.还有万一有人闯空门 ...

  3. 动态网页爬取样例(WebCollector+selenium+phantomjs)

    目标:动态网页爬取 说明:这里的动态网页指几种可能:1)须要用户交互,如常见的登录操作:2)网页通过JS / AJAX动态生成.如一个html里有<div id="test" ...

  4. JAVA并发--volatile

    学过计算机组成原理的一定知道,为了解决内存速度跟不上CPU速度这个问题,在CPU的设计中加入了缓存机制,缓存的速度介于CPU和主存之间.在进行运算的时候,CPU将需要的数据映射一份在缓存中,然后直接操 ...

  5. [BZOJ4826][HNOI2017]影魔 可持久化线段树

    链接 题意:给你 \(1\) 到 \(n\) 的排列 \(k_1,k_2,\dots,k_n\) ,对 \(i,j (i<j)\)来说,若不存在 \(k_s (i<s<j)\) 大于 ...

  6. 相比于HTML4,HTML5废弃的元素有哪些?

    第一类:表现性元素basefontbigcenterfontsstrikettu建议用语义正确的元素代替他们,并使用CSS来确保渲染后的效果 第二类:框架类元素因框架有很多可用性及可访问性问题,HTM ...

  7. 互联网金融研究组:P2P借贷平台:性质、风险与监管(上)

    互联网金融研究组(): P2P借贷平台:性质.风险与监管(上) 目 录 一.性质与合法性 1.  P2P网络借贷 1.1  概念重新界定 1.2  发展概况与特点 2.  延伸模式及其合法性浅析 2. ...

  8. Atcoder Grand Contest 107 A Biscuits

    A - Biscuits Time limit : 2sec / Memory limit : 256MB Score : 200 points Problem Statement There are ...

  9. 如何在Ubuntu14.04中安装mysql

    接触过MySQL的小伙伴们都知道,在Windows下安装MySQL是一件让人十分头大的事情,但是在Ubuntu等其他Linux系统中安装MySQL就简单很多了,具体的教程如下.1.在Ubuntu的命令 ...

  10. Android布局之LinearLayout

    LinearLayout 1.核心属性 高度:layout_height   (基于内容 wrap_content:基于父控件:) 宽度:layout_width 方向:orientation  (纵 ...