http://acm.hdu.edu.cn/showproblem.php?pid=6662

仿照 CC B - TREE 那道题的思路写的,差不多。也是要走路径。

像这两种必须走到叶子的路径感觉是必须从INF出发,使得它强制从子树转移过来。否则假如可以在中间节点中断的话,初始值就是0,转移的时候假如子树更不好就不会更新这个0。

与哪个求每个点去往的最远点的标号(同样远的求最小标号)类似。

f[u]表示从u节点向下走向子树的最优值,这样必须dfs到叶子然后初始化叶子再返回。

g[u]表示从u节点向上走到父亲p,然后从父亲p绕另一条路(要么是走到祖父,要么是走到兄弟,所以f[p]要记录次优值以及最优值走向哪个儿子)的最优值,dfs的时候初始化根为它本身。

这样子定义导致在统计答案的时候要特判。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int MAXN = 1e5 + 5; ll val[MAXN]; vector<int> E[MAXN]; int ROOT; void dfs1(int u, int p) {
if(E[u].size() == 1) {
ROOT = u;
return;
}
for(auto v : E[u]) {
if(v == p)
continue;
dfs1(v, u);
if(ROOT != -1)
return;
}
} const ll INF = 1e18 + 1e17;
const ll INF2 = 1e16; struct F {
ll val;
int son;
} fm1[MAXN], fm2[MAXN], fM1[MAXN], fM2[MAXN], tmpm, tmpM; inline void InitF(int n) {
for(int i = 1; i <= n; ++i) {
fm1[i].val = fm2[i].val = INF;
fM1[i].val = fM2[i].val = -INF;
fm1[i].son = fm2[i].son = fM1[i].son = fM2[i].son = -1;
}
} void maintainF(int u, int v) {
if(tmpM.val < fm2[u].val) {
fm2[u] = tmpM;
fm2[u].son = v;
if(fm2[u].val < fm1[u].val) {
swap(fm1[u], fm2[u]);
}
}
if(tmpm.val > fM2[u].val) {
fM2[u] = tmpm;
fM2[u].son = v;
if(fM2[u].val > fM1[u].val) {
swap(fM1[u], fM2[u]);
}
}
} void dfsF(int u, int p) {
if(E[u].size() == 1 && E[u][0] == p) {
fm1[u].val = val[u];
fM1[u].val = val[u];
fm1[u].son = u;
fM1[u].son = u;
return;
}
for(auto v : E[u]) {
if(v == p)
continue;
dfsF(v, u);
tmpM = fM1[v];
tmpm = fm1[v];
maintainF(u, v);
}
fm1[u].val += val[u];
fm2[u].val += val[u];
fM1[u].val += val[u];
fM2[u].val += val[u];
} struct G {
ll val;
} gm[MAXN], gM[MAXN]; inline void InitG(int n) {
for(int i = 1; i <= n; ++i) {
gm[i].val = INF;
gM[i].val = -INF;
}
} F getFm(int u, int p) {
if(fm1[p].son == u)
return fm2[p];
return fm1[p];
} F getFM(int u, int p) {
if(fM1[p].son == u)
return fM2[p];
return fM1[p];
} void maintainG(int u, int p) {
if(p == -1) {
gm[u].val = val[u];
gM[u].val = val[u];
return;
}
gm[u].val = max(getFM(u, p).val, gM[p].val) + val[u];
gM[u].val = min(getFm(u, p).val, gm[p].val) + val[u];
} void dfsG(int u, int p) {
maintainG(u, p);
for(auto v : E[u]) {
if(v == p)
continue;
dfsG(v, u);
}
} int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
int T;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%lld", &val[i]);
for(int i = 1, b; i <= n; ++i) {
scanf("%d", &b);
val[i] -= b;
}
for(int i = 1; i <= n; ++i)
E[i].clear();
for(int i = 1; i <= n - 1; ++i) {
int u, v;
scanf("%d%d", &u, &v);
E[u].push_back(v);
E[v].push_back(u);
}
ROOT = -1;
dfs1(1, -1);
//ROOT是其中一个叶子
InitF(n);
dfsF(ROOT, -1);
InitG(n);
dfsG(ROOT, -1);
ll ans = -INF;
for(int i = 1; i <= n; ++i) {
ll tmp = (E[i].size() == 1 && i != ROOT ? INF : fm1[i].val);
tmp = min(tmp, (i != ROOT) ? (gm[i].val) : INF);
ans = max(ans, tmp);
}
printf("%lld\n", ans);
}
return 0;
}

假如定义f和g不包含节点本身的话,那是不是不需要特判呢?只能说是判得更恶心了。

2019 Multi-University Training Contest 8 - 1006 - Acesrc and Travel - 树形dp的更多相关文章

  1. 吉首大学2019年程序设计竞赛(重现赛)-J(树形DP)

    题目链接:https://ac.nowcoder.com/acm/contest/992/J 题意:题意很清晰,就是求任意两点距离的和,结果对1e9+7取模. 思路:裸的树形DP题,一条边的贡献值=这 ...

  2. 2019 Multi-University Training Contest 7 - 1006 - Snowy Smile - 线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=6638 偷学一波潘哥的二维离散化和线段树维护最大子段和. 思路是枚举上下边界,但是不需要从左到右用最大子段和dp. ...

  3. 2019 Multi-University Training Contest 3 - 1006 - Fansblog - 打表 - 暴力

    http://acm.hdu.edu.cn/showproblem.php?pid=6608 题意:给一个比较大的质数P(1e14以内),求比它小的最大的质数Q(貌似保证存在的样子,反正我没判不存在) ...

  4. 2015 Multi-University Training Contest 2 1006 Friends

    Friends Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5305 Mean: n个人,m对朋友关系,每个人的朋友中又分为在线 ...

  5. 2015 Multi-University Training Contest 3 1006 Beautiful Set

    Beautiful Set Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5321 Mean: 给出一个集合,有两种计算集合的值的 ...

  6. HDU 6324.Problem F. Grab The Tree-博弈(思维) (2018 Multi-University Training Contest 3 1006)

    6324.Problem F. Grab The Tree 题目看着好难,但是题解说的很简单,写出来也很简单.能想出来就是简单的,想不出来就难(讲道理,就算是1+1的题目,看不出来就是难的啊). 和后 ...

  7. 2015 Multi-University Training Contest 2 1006 Friends 壮压

    题目链接 题意:t 组測试数据,每组測试数据有 n个人,m条关系 每条关系能够是 "线上关系" 或者 "线下关系". 要求每一个人的线上关系(条数) == 线下 ...

  8. 2019 Nowcoder Multi-University Training Contest 4 E Explorer

    线段树分治. 把size看成时间,相当于时间 $l$ 加入这条边,时间 $r+1$ 删除这条边. 注意把左右端点的关系. #include <bits/stdc++.h> ; int X[ ...

  9. 2019 Nowcoder Multi-University Training Contest 1 H-XOR

    由于每个元素贡献是线性的,那么等价于求每个元素出现在多少个异或和为$0$的子集内.因为是任意元素可以去异或,那么自然想到线性基.先对整个集合A求一遍线性基,设为$R$,假设$R$中元素个数为$r$,那 ...

随机推荐

  1. 在浏览器访问Tomcat的时候报错java.lang.IllegalArgumentException: Control character in cookie value or attribute.

    出现这种情况的原因就是因为cookie中存在中文或者特殊符号造成的,应为Tomcat7不支持 解决方法: 1,首先必须先删除本地的cookie,否则项目无法访问 2,然后调整编码就行了

  2. C++入门经典-例6.18-数组的动态分配,动态获得斐波那契数列

    1:有时在获得一定的信息之前,我们并不确定数组的大小.动态分配数组则可以使用变量作为数组的大小,使数组的大小符合我们的要求. 2:科普一下斐波纳契数列:斐波那契数列指的是这样一个数列 1, 1, 2, ...

  3. 10、kubernetes之RBAC认证

    一.kubectl proxy # kubectl proxy --port=8080 # curl http://localhost:8080/api/v1/ # curl http://local ...

  4. LeetCode 74. 搜索二维矩阵(Search a 2D Matrix)

    题目描述 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的最后一个整数. 示例 1: 输入: ma ...

  5. centos6 yum安装mysql 5.6 (完整版)

    使用源代码编译安装mysql还是比较麻烦,一般来说设备安装时请网络同事临时开通linux上网,通过yum网络实现快速安装,或配置yum仓库进行内网统一安装. 通过网络快速安装过程如下 一.检查系统是否 ...

  6. 使用tensorflow.data.Dataset构造batch数据集(具体用法在下一篇博客介绍)

    import tensorflow as tf import numpy as np def _parse_function(x): num_list = np.arange(10) return n ...

  7. leetcode172 阶乘后的零

    对数算法:O(nlogn) /** 即为统计0-n中5,10,15,20,25的个数,因为肯定有足够的偶数使得存在x*5=10*n,25=5*5因此计数加2,5=1*5计数加一: 但如果挨个计数当n很 ...

  8. 代码实现:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%; 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%; 20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%; 60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元

    import java.util.Scanner; /* 企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成 ...

  9. MySQL 5.7.27 MGR 单主/多主+ ProxySQL

    1 MySQL 5.7.27 MGR 多主环境 基础信息如下: centos 6.5/vbox 实例名 A B C IP 10.15.7.29 10.15.7.28 10.15.7.27 实例端口号 ...

  10. jdbc简单连接oracle数据库

    package com.shangsheng; import java.sql.*; public class UserOracle { public static void main(String[ ...