问题等价于树形依赖背包,允许一条链每个点各免费一次。

设$f[i][j]$表示按DFS序考虑到$i$,体积为$j$的最大收益。

先放入不能免费的物品,等遍历完儿子后再放入必选的物品,那么$i$到根路径上所有点都只算了不能免费的部分。

然后将DFS序翻转,设$h[i][j]$表示按DFS序考虑到$i$,体积为$j$的最大收益。

等遍历完儿子后再放入必选的物品和不能免费的物品,那么$i$到根路径上所有点都没有算。

如此一来,对于每个叶子$i$,用$f[i][j]+h[i][k-j]$更新答案即可。

对于不能免费的物品,需要用单调队列优化转移。

时间复杂度$O(nk)$。

#include<cstdio>
#include<cstring>
const int N=20010,M=25520010;
int Case,n,m,K,T,i,fa[N],a[N],b[N],g[N],nxt[N],ans,F[M],H[M];
inline void add(int x,int y){nxt[y]=g[x];g[x]=y;}
inline void up(int&a,int b){a<b?(a=b):0;}
inline void solve(int*f,int A,int B){
int i,j=0,h=1,t=0;
static int q[500010],p[500010];
for(i=0;i<=m;i++,j+=B){
f[i]-=j;
while(h<=t&&f[q[t]]<f[i])t--;
q[++t]=i;
while(i-q[h]>A)h++;
p[i]=f[q[h]]+j;
}
memcpy(f,p,T);
}
void dfsl(int x){
int i,j,A=a[x],B=b[x];
if(A)solve(F+x*K,A,B);
for(i=g[x];i;i=nxt[i]){
memcpy(F+i*K,F+x*K,T);
dfsl(i);
B=b[i];
int*s=F+x*K+1,*e=F+i*K;
for(j=1;j<=m;j++,s++,e++)up(*s,*e+B);
}
}
void dfsr(int x,int y){
int i,j,A=a[x],B=b[x];
y+=B;
for(i=g[x];i;i=nxt[i]){
memcpy(H+i*K,H+x*K,T);
dfsr(i,y);
B=b[i];
int*s=H+x*K+1,*e=H+i*K;
for(j=1;j<=m;j++,s++,e++)up(*s,*e+B);
}
if(!g[x]){
int*s=H+x*K+m,*e=F+x*K;
for(j=0;j<=m;j++,s--,e++)up(ans,*s+*e+y);
}
if(A)solve(H+x*K,A,b[x]);
}
int main(){
scanf("%d",&Case);
while(Case--){
scanf("%d%d",&n,&m);
K=m+1;T=K*sizeof(int);
for(i=1;i<=n;i++)g[i]=0;
for(i=1;i<=n;i++){
scanf("%d%d%d",&fa[i],&a[i],&b[i]);a[i]--;
if(fa[i])add(fa[i],i);
}
memset(F+K,0,T);
memset(H+K,0,T);
dfsl(1);
for(i=1;i<=n;i++)g[i]=0;
for(i=n;i;i--)if(fa[i])add(fa[i],i);
ans=0;
dfsr(1,0);
printf("%d\n",ans);
}
return 0;
}

  

BZOJ4910 : [Sdoi2017] 苹果树的更多相关文章

  1. [SDOI2017]苹果树

    题目描述 https://www.luogu.org/problemnew/show/P3780 题解 一道思路巧妙的背包题. 对于那个奇怪的限制,我们对此稍加分析就可以发现它最后选择的区域是一个包含 ...

  2. sdoi2017苹果树

    题解: 非常奇妙的一题.. 没有免费操作我都不会$nk$....考试打个暴力就可以走人了 树上有依赖背包问题的正确做法是(为啥我之前学的不是这样的啊) 按照后续遍历做背包 做到一个点的时候 枚举它选不 ...

  3. BZOJ.4910.[SDOI2017]苹果树(树形依赖背包 DP 单调队列)

    BZOJ 洛谷 \(shadowice\)已经把他的思路说的很清楚了,可以先看一下会更好理解? 这篇主要是对\(Claris\)题解的简单说明.与\(shadowice\)的做法还是有差异的(比如并没 ...

  4. 【做题】SDOI2017苹果树——dfs序的运用

    原文链接 https://www.cnblogs.com/cly-none/p/9845046.html 题意:给出一棵\(n\)个结点的树,在第\(i\)个结点上有\(a_i\)个权值为\(v_i\ ...

  5. hs-black 杂题选讲

    [POI2011]OKR-Periodicity 考虑递归地构造,设 \(\text{solve(s)}\) 表示字典序最小的,\(\text{border}\) 集合和 \(S\) 的 \(\tex ...

  6. DP 优化小技巧

    收录一些比较冷门的 DP 优化方法. 1. 树上依赖性背包 树上依赖性背包形如在树上选出若干个物品做背包问题,满足这些物品连通.由于 01 背包,多重背包和完全背包均可以在 \(\mathcal{O} ...

  7. 【LOJ】#2268. 「SDOI2017」苹果树

    题解 显然权值都是正的,我们最深的那个点一定延伸到了某个叶子 我们抛去这条链之外再选K个点即可 如果直接对一棵树选K个点,满足这样的依赖关系,可以通过一个后序遍历的顺序做出来 转移方法是 \(dp[i ...

  8. SDOI2017 Round2 详细题解

    这套题实在是太神仙了..做了我好久...好多题都是去搜题解才会的 TAT. 剩的那道题先咕着,如果省选没有退役就来填吧. 「SDOI2017」龙与地下城 题意 丢 \(Y\) 次骰子,骰子有 \(X\ ...

  9. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

随机推荐

  1. 饮冰三年-人工智能-Python-10之C#与Python的对比

    1:注释 C# 中 单行注释:// 多行注释:/**/ python 中 单行注释:# 多行注释:“““内容””” 2:字符串 C#中 "" 用双引号如("我是字符串&q ...

  2. Java接口自动化测试之TestNG学习(二)

    在maven项目的pom.xml文件中导入TestNG <?xml version="1.0" encoding="UTF-8"?> <pro ...

  3. Fisher–Yates shuffle 算法

    费希尔 - 耶茨洗牌 维基百科,自由的百科全书     所述费-耶茨洗牌是一种算法,用于产生随机排列的有限的序列 -in平原而言,算法打乱的序列.该算法有效地将所有元素放在帽子里; 它通过随机从帽子中 ...

  4. C. cltt的幸运数LCAtarjan

    /*C: cltt的幸运数 Time Limit: 1 s      Memory Limit: 128 MB Submit Problem Description 一棵树有n个节点,共m次查询,查询 ...

  5. Sqoop使用,mysql,hbase,hive等相互转换

    Sqoop 是一款用来在不同数据存储软件之间进行数据传输的开源软件,它支持多种类型的数据储存软件. 安装 Sqoop 1.下载sqoop并加mysql驱动包 http://mirror.bit.edu ...

  6. 新的表格展示利器 Bootstrap Table Ⅰ

     1.bootstrap table简介及特征 Bootstrap Table是国人开发的一款基于 Bootstrap 的 jQuery 表格插件,通过简单的设置,就可以拥有强大的单选.多选.排序.分 ...

  7. 记录一次因代理Controller产生的404问题

    spring 3.2.4 为了给每一个controller配置一个拦截器链 import com.google.common.collect.Lists; import org.aopalliance ...

  8. [转] React 中组件间通信的几种方式

    在使用 React 的过程中,不可避免的需要组件间进行消息传递(通信),组件间通信大体有下面几种情况: 父组件向子组件通信 子组件向父组件通信 跨级组件之间通信 非嵌套组件间通信 下面依次说下这几种通 ...

  9. 【UOJ 209】【UER #6】票数统计

    题解: jls的题目还是比较好的 首先比较显然我们可以分析出 当x<y时,显然只能满足前缀条件 针对这一档部分分,是个简单的组合数 考虑一下后缀限制,发现真的不好搞.. 看了题解发现,枚举总共的 ...

  10. day9文件操作---从即日起时景丽阳老师给我们讲课

    今天的主要内容是文件的操作,读,写,只读只写,或者可读同时可写,追加写,以二进制的方式读,以二进制的方式写,以二进制的方式追加. 思维导图: 给你一个文件路径,从中找出所有的文件,方法如下: # 方法 ...