2020牛客多校9:B. Groundhog and Apple Tree(树形DP + 分类讨论 + 贪心)
题目大意:有一棵苹果树,每个节点有一个苹果,吃掉 uuu 点的苹果能获得 aua_uau点 HP,经过第 iii 条边需要消耗 wiw_iwi HP,在原地等待一秒可以获得 111 HP,每条边只能经过两次,问从1号节点出发吃掉所有苹果最少需要等待多少秒。
分析:首先在某个点一次性把所需要的HP等够是显然正确的,根据每条边只能经过两次,解的形式一定是先吃掉某棵子树,再回到根,再吃其它子树,最优解是一个吃的顺序的问题,而吃掉子树是一个子问题,考虑用树形 dp。
设 dp[u]dp[u]dp[u] 表示以 uuu 为根的答案, sum[u]sum[u]sum[u] 表示吃完 uuu 的子树后 HP 的变化。
sum[u]sum[u]sum[u] 转移方程:sum[u]=∑v∈son(u)(sum[v]−2∗wv)sum[u] = \sum_{v\in son(u)}(sum[v] - 2 * w_v)sum[u]=∑v∈son(u)(sum[v]−2∗wv)
dp[u]dp[u]dp[u] 的转移要考虑子树的遍历顺序。
对于第 iii 棵子树,进入到这棵子树需要 ai=dp[i]+wia_i = dp[i] + w_iai=dp[i]+wi,从他回到 uuu 后 得到的 HP 为 bi=dp[i]+sum[i]−wib_i=dp[i]+sum[i]-w_ibi=dp[i]+sum[i]−wi
对遍历顺序进行分类讨论,简化问题,考虑只有两棵子树时的遍历顺序:
先遍历 bi≥aib_i \geq a_ibi≥ai 的子树更优:
设有 ai≤bi,aj>bja_i \leq b_i,a_j > b_jai≤bi,aj>bj,分别讨论先 iii 和先 jjj 的答案:
1、若 ai≥aja_i \geq a_jai≥aj,则两种情况答案分别为:aia_iai, aj+ai−bja_j + a_i - b_jaj+ai−bj
2、若 ai<aja_i < a_jai<aj,则两种情况答案分别为:ai+max(aj−bi,0)a_i + max(a_j - b_i,0)ai+max(aj−bi,0) , aj+max(ai−bj,0a_j + max(a_i - b_j,0aj+max(ai−bj,0,画一下发现先 iii 答案至多为 aja_jaj,而先 jjj 答案至少为 aja_jaj
若均满足 a<ba<ba<b:
设有 ai≤bi,aj≤bja_i \leq b_i, a_j \leq b_jai≤bi,aj≤bj,设 ai<aja_i < a_jai<aj
两种情况答案分别为:ai+max(aj−bi,0)a_i + max(a_j - b_i,0)ai+max(aj−bi,0),aja_jaj,由于 bi≥aib_i \geq a_ibi≥ai,显然有 ai+max(aj−bi,0)≤aja_i + max(a_j - b_i,0) \leq a_jai+max(aj−bi,0)≤aj
若均满足 a>ba>ba>b:
设有 ai>bi,aj>bja_i > b_i, a_j > b_jai>bi,aj>bj
两种情况分别为:ai+max(aj−bi,0)a_i + max(a_j - b_i,0)ai+max(aj−bi,0),aj+max(ai−bj,0)a_j + max(a_i - b_j,0)aj+max(ai−bj,0),在纸上画一下可以发现先遍历 bbb 更大的子树更优。
代码:
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
typedef long long ll;
const int maxn = 1e5 + 10;
vector<pii> g[maxn];
int t, n, a[maxn];
ll dp[maxn], sum[maxn];
struct node {ll in, out;node() {}node(ll i,ll j) {in = i, out = j;}
};
bool cmp1(node x,node y) {return x.in < y.in;
}
bool cmp2(node x,node y) {return x.out > y.out;
}
void dfs(int u,int fa) {dp[u] = 0, sum[u] = a[u];vector<node> x, y;for (auto it : g[u]) {int v = it.fir, w = it.sec;if (v == fa) continue;dfs(v,u);sum[u] += sum[v] - 2ll * w;node t;if (w <= dp[v] + sum[v])t = node(w + dp[v],dp[v] + sum[v] - w);elset = node(2ll * w - sum[v],0);if (t.in <= t.out)x.push_back(t);elsey.push_back(t);}sort(x.begin(),x.end(),cmp1);sort(y.begin(),y.end(),cmp2);ll cur = a[u];for (auto it : x) {if (it.in > cur) {dp[u] += it.in - cur;cur = it.in;}cur = cur - it.in + it.out;}for (auto it : y) {if (it.in > cur) {dp[u] += it.in - cur;cur = it.in;}cur = cur - it.in + it.out;}
}
int main() {scanf("%d",&t);while (t--) {scanf("%d",&n);for (int i = 1; i <= n; i++)g[i].clear();for (int i = 1; i <= n; i++)scanf("%d",&a[i]);for (int i = 1; i < n; i++) {int u, v, w;scanf("%d%d%d",&u,&v,&w);g[u].push_back(pii(v,w));g[v].push_back(pii(u,w));}dfs(1,0);printf("%lld\n",dp[1]);}return 0;
}
2020牛客多校9:B. Groundhog and Apple Tree(树形DP + 分类讨论 + 贪心)相关推荐
- 2020 牛客多校第一场
2020 牛客多校第一场 A. B-Suffix Array 后缀数组的思想:倍增+桶排序的方式找出一串连续序列后缀的大小.虽说正常使用的时候都是字典序,但是只要修改排序方式,也能够达到一个类似的&q ...
- 2020牛客多校 J Easy Integration 计算过程详解【点火公式(Wallis积分)+组合数学】
2020牛客暑期多校训练营(第一场) J Easy Integration 题 网上题解大多是 不断分部积分求解,其实有更为简洁的解法. 便是 Wallis积分(点火公式) + 组合数学 求解,本文给 ...
- 【牛客 - 157D】插排树(dfs,树形dp)
题干: 链接:https://ac.nowcoder.com/acm/contest/157/D 来源:牛客网 一年一度的山东省oi夏令营又开始了,每到这个季节,山东的oier们都会欢聚这里,一起学( ...
- [2020牛客多校第一场]Coda的题解集
被暴打了. 会先写比赛中过题数100+的题目,其他的以后再补. 施工中,未完待续- F Infinite String Comparision 一开始想到的是对比到lcm(|a|,|b|),意料之中T ...
- 2020牛客多校联赛第四场 (BFH)
文章目录 B:Basic Gcd Problem 题目 翻译 例子 大意 思路 代码 F:Finding the Order 题目 翻译 例子 大意 思路 代码 H:Harder Gcd Proble ...
- 2020牛客多校第1场H-Minimum-cost Flow
解题思路: 首先我们要从费用流mcmf的算法入手:因为它每次增广是再费用增广路上跑的,根据贪心的思想费用小的路基本上能运多少就尽量运多少,所以我们可以假设初始的边容量是1,只跑一遍mcmf.记录一下每 ...
- 数论分块 ---- 2020牛客多校第7场H-Dividing[思维+数论分块]
题目大意: 解题思路:很明显满足条件的点是n%k==0∣∣n%k==1n\%k==0||n\%k==1n%k==0∣∣n%k==1 1.因为nnn是从111开始的如果一直乘以k[n=n∗k]k[n=n ...
- 2020牛客多校第7场C-A National Pandemic[树链剖分+思维]
题目大意 1.首先我们看一下操作1:实际上可以说成在所有位置上加上w−dist(x,y)w-dist(x,y)w−dist(x,y),因为dist(x,x)=0dist(x,x)=0dist(x,x) ...
- 2020牛客多校第一场B虚树+质数筛+换根dp
题目大意: 1.可以发现阶乘增长是很快的所以你要把整颗树建立出来是不实际的. 2.我们可以假设这棵树已经建出来出来了我们应该怎么搞 首先很明显是一个树形dp, 我们设dp[j],是以j为u到其他点距离 ...
最新文章
- CSS中一些语法规范和代码风格
- Science 好文:强化学习之后,机器人学习瓶颈如何突破?
- KS008基于SSM的新闻发布系统
- Xcode12.5最新快捷键的使用(学会事半功倍)
- 敏捷 冲刺_在这个敏捷的假期季节给予技术债务冲刺的礼物
- linux 刻录cd,Linux 刻录CD/DVD命令 growisofs/mkisofs/cdrecord
- 推荐系统(2)-协同过滤1-UserCF、ItemCF
- TensorFlow 学习指南 四、分布式
- C#(asp.net)实现目录(无扩展名)重写
- 以京东为代表电商平台成中华老字号销售增速最快渠道
- 【Flutter】Dart中的Mixins混入你知道是什么吗?
- core部署iis的 调试net_ASP.NET Core环境变量和启动设置的配置教程
- 传输层的端口与TCP标志中的URG和PSH位
- 五大地形等高线特征_【新微专题】从等高线地形图的实际应用分析如何培养图表判读能力?...
- Wex5 app 学习笔记(二)
- DATABASE_ROUTERS在Django中使用多个MySQL数据库进行配置
- AFNetworkReachabilityManager检测网络状态
- excel2019如何做下拉菜单选项(数据源不占用原表上的单元格)
- c语言(http://c.biancheng.net/view/1714.html)
- 【Java专题】Java中的I/O流详解
热门文章
- 银行携手基金推类“余额宝”产品
- C++学习笔记_002_对象特性(续)
- 【过一下6】机器视觉视频 【过一下2被挤掉了】
- Leetcode周赛专题
- TZC 1283: 简单排序 —— 比较排序
- 夏季养生保健 10个常识女人夏季养生必备
- 十、矩阵零空间、线性无关、列空间、列空间的基、零度、秩等概念的整合
- linux网络协议栈招聘,Linux 网络协议栈开发(一)ping命令
- ad敷铜后还有部分飞线_AP刺客才是刺客之王!虎牙整活杯刺客大战,AD刺客遗憾落败...
- 【知识蒸馏】2021年最新知识蒸馏综述和论文总结