BZOJ4182: Shopping(点分治,树上背包)
Description
马上就是小苗的生日了,为了给小苗准备礼物,小葱兴冲冲地来到了商店街。商店街有n个商店,并且它们之间的道路构成了一颗树的形状。
Input
输入第一行一个正整数T,表示测试数据组数。
Output
Sample Input
3 2
1 2 3
1 1 1
1 2 1
1 2
1 3
Sample Output
解题思路:
可以发现答案最后是一颗子树,所以我们只需要枚举子树就好了,由于根节点不定,所以靠点分治来实现枚举根(如果答案比一个子树大,那么一点会经过这个根),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(点分治,树上背包)的更多相关文章
- [BZOJ4182]Shopping (点分治+树上多重背包+单调队列优化)
[BZOJ4182]Shopping (点分治+树上多重背包+单调队列优化) 题面 马上就是小苗的生日了,为了给小苗准备礼物,小葱兴冲冲地来到了商店街.商店街有n个商店,并且它们之间的道路构成了一颗树 ...
- BZOJ 4182 Shopping (点分治+树上多重背包)
题目大意:给你一颗树,你有$m$元钱,每个节点都有一种物品,价值为$w$,代价为$c$,有$d$个,如果在$u$和$v$两个城市都购买了至少一个物品,那么$u,v$路径上每个节点也都必须买至少一个物品 ...
- bzoj4182 Shopping 点分治+单调队列优化多重背包
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4182 题解 有一个很直观的想法是设 \(dp[x][i]\) 表示在以 \(x\) 为根的子树 ...
- HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)
题目链接 2017 CCPC Hangzhou Problem E 题意 给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...
- Hdu 6268 点分治 树上背包 bitset 优化
给你一颗大小为n(3000)的树,树上每个点有点权(100000),再给你一个数m(100000) i为1~m,问树中是否存在一个子图,使得权值为i. 每次solve到一个节点 用一个bitset维护 ...
- bzoj4182/luoguP6326 Shopping(点分治,树上背包)
bzoj4182/luoguP6326 Shopping(点分治,树上背包) bzoj它爆炸了. luogu 题解时间 如果直接暴力背包,转移复杂度是 $ m^{2} $ . 考虑改成点分治. 那么问 ...
- HDU4044 GeoDefense(有点不一样的树上背包)
题目大概说一棵n个结点的树,每个结点都可以安装某一规格的一个塔,塔有价格和能量两个属性.现在一个敌人从1点出发但不知道他会怎么走,如果他经过一个结点的塔那他就会被塔攻击失去塔能量的HP,如果HP小于等 ...
- luogu 2014 选课 树上背包
树上背包 #include<bits/stdc++.h> using namespace std; ; const int inf=0x3f3f3f3f; vector<int> ...
- Crazy Shopping(拓扑排序+完全背包)
Crazy Shopping(拓扑排序+完全背包) Because of the 90th anniversary of the Coherent & Cute Patchouli (C.C. ...
随机推荐
- Objective-C - NSInteger转换NSString
NSInteger不是对象, 转换为long匹配64位系统, 再组成字符串(%ld). NSString *inStr = [NSString stringWithFormat: @"%ld ...
- 巧用FPGA中资源
随着FPGA的广泛应用,所含的资源也越来越丰富,从基本的逻辑单元.DSP资源和RAM块,甚至CPU硬核都能集成在一块芯片中.在做FPGA设计时,如果针对FPGA中资源进行HDL代码编写,对设计的资源利 ...
- Flask Flash闪现
Flash介绍以及工作方式 flash中添加消息 取出flash中的消息 Flash介绍以及工作方式 - 介绍: flash :闪现 一个好的应用和用户界面都需要良好的反馈. 如果用户得不到足够的反馈 ...
- 版本控制Git(1)——理解暂存区
一.svn和Git的比较 我们都知道传统的源代码管理都是以服务器为中心的,每个开发者都直接连在中间服务器上, 本地修改,然后commit到svn服务器上.这种做法看似完美,但是有致命的缺陷. 1. 开 ...
- 网站及监控利器 Pandora FMS使用体验
Pandora FMS 是一个 开源的应用程序 ,用来监测网站的各种活动,它可以收到实时的监测报告,并发送到你指定的邮箱,也可以通过e-mail, SMS 发送. 650) this.width=65 ...
- Network Stack : HTTP Cache
HTTP Cache 目录 1 Operation 2 Sparse Entries 3 Truncated Entries 4 Byte-Range Requests 5 HttpCache::Tr ...
- javaScript for in循环遍历对象
for循环常被我们用来遍历数组,而如何遍历对象呢? 这时就需要用到for in循环了 写一个遍历对象名简写如下: for(var xxx in ooo){console.log(xxx)} 其中xxx ...
- 【python 设计模式】单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. 比如,某 ...
- Tomcat会话超时时怎样记录操作日志,满足安全审计要求
众所周知.在实际的Web应用程序中,会话管理一般都採用Web容器会话管理功能. 使用Tomcat做Webserver也是如此,并且从安全的角度考虑,尽量避免去更改和干预Web容器的会话管理功能. To ...
- 你如何理解 HTML5 的 section?会在什么场景使用?为什么这些场景使用 section 而不是 div?
section元素表示文档或应用的一个部分.所谓“部分”,这里是指按照主题分组的内容区域,通常会带有标题.[也就是每个section对应不同的主题.注意是内容本身的主题,而不是其他人为设定的划分标准. ...