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

题意:有两个人在树上博弈,每个点节点有两个分数a[i]和b[i],先手先选择一个点,后手在先手选的点的相邻点中选择一个点,然后先手在后手选的点的相邻点中选择一个两个人都没有走过的点,直到不能走,游戏就结束。一个人走到节点x,那么先手会获得分数a[x],后手就会会获得分数b[x]。最后询问先手能获得与后手的差值最大值。

思路:先手固定好位置后,后手走。有两种走法,向下和向上。

向下好办,用down[i][0]表示我从i走到i的儿子后所能得到的最大值,down[i][1]为对手走的最小值,那么down[i][0] = v[i]+max(down[son][1]), down[i][1]=v[i]+min(down[son][0])

向上的话,走完后对面也分为向上或向下。

向下走时,不能走当前上去的路,所以存每个点向下走的最值和次值,当最值和上去那条路得出的值相同,就换成次值。

向上走时,从上到下一路维护即可。

 #include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 1e5+;
const ll inf = 0x3f3f3f3f3f3f3f3f;
ll a[maxn],b[maxn];
int head[maxn],fa[maxn],to[maxn<<],nex[maxn<<],now; void add(int a,int b){
nex[++now] = head[a];
head[a] = now;
to[now] = b;
} ll down[maxn][][],up[maxn][];
bool lef[maxn]; void dfs(int p){
down[p][][] = down[p][][] = -inf;
down[p][][] = down[p][][] = inf;
lef[p] = ;
for(int i=head[p];i;i=nex[i]){
if(to[i]==fa[p]) continue;
lef[p] = ;
fa[to[i]] = p;
dfs(to[i]);
if(down[to[i]][][]+a[p]>=down[p][][]){
down[p][][] = down[p][][];
down[p][][] = down[to[i]][][]+a[p];
}
else if(down[to[i]][][]+a[p]>=down[p][][]){
down[p][][] = down[to[i]][][]+a[p];
}
if(down[to[i]][][]+a[p]<=down[p][][]){
down[p][][] = down[p][][];
down[p][][] = down[to[i]][][]+a[p];
}
else if(down[to[i]][][]+a[p]<=down[p][][]){
down[p][][] = down[to[i]][][]+a[p];
}
}
if(lef[p]) down[p][][] = down[p][][] = a[p];
} ll Abs(ll a){
return a>?a:-a;
} void Dfs(int p){
if(fa[p]==-) up[p][] = up[p][] = inf;
else {
up[p][] = inf;
ll _down = down[fa[p]][][];
if(_down==a[fa[p]]+down[p][][])
_down = down[fa[p]][][];
if(Abs(_down)!=inf)
up[p][] = min(up[p][],a[p]+_down);
if(fa[p]!=)
up[p][] = min(up[p][],a[p]+up[fa[p]][]);
if(up[p][]==inf)
up[p][] = a[p]+a[fa[p]]; up[p][] = -inf;
_down = down[fa[p]][][];
if(_down==a[fa[p]]+down[p][][])
_down=down[fa[p]][][];
if(Abs(_down)!=inf)
up[p][]=max(up[p][],a[p]+_down); if(fa[p]!=)
up[p][]=max(up[p][],a[p]+up[fa[p]][]); if(up[p][]==-inf)
up[p][]=a[p]+a[fa[p]];
}
for(int i=head[p];i;i=nex[i]){
if(to[i]==fa[p])continue;
Dfs(to[i]);
}
} int main(){
ios::sync_with_stdio();
cin.tie();
cout.tie();
int t;
cin>>t;
while(t--){
memset(head,,sizeof head);
now = ;
int n;
cin>>n;
rep(i,,n) cin>>a[i];
rep(i,,n) cin>>b[i], a[i]-=b[i];
rep(i,,n-){
int u,v;
cin>>u>>v;
add(u,v);
add(v,u);
}
if(n==){
cout<<a[]<<endl;
continue;
}
fa[] = -;
dfs();
Dfs();
ll ans = -inf;
for(int i=;i<=n;i++){
ll res = inf;
if(!lef[i]) res = min(res,down[i][][]);
if(i!=) res = min(res,up[i][]);
ans = max(ans,res);
}
cout<<ans<<endl;
}
return ;
}

2019杭电多校 hdu6662 Acesrc and Travel (树形dp的更多相关文章

  1. 2019杭电多校 hdu6659 Acesrc and Good Numbers

    http://acm.hdu.edu.cn/showproblem.php?pid=6659 题意:给你d,x,让求满足f(d,n)=n的最大n(n<=x),其中f(d,n)表示数字d在从1到n ...

  2. 2019 Multi-University Training Contest 8 - 1006 - Acesrc and Travel - 树形dp

    http://acm.hdu.edu.cn/showproblem.php?pid=6662 仿照 CC B - TREE 那道题的思路写的,差不多.也是要走路径. 像这两种必须走到叶子的路径感觉是必 ...

  3. 2019杭电多校&CCPC网络赛&大一总结

    多校结束了, 网络赛结束了.发现自己还是太菜了,多校基本就是爆零和签到徘徊,第一次打这种高强度的比赛, 全英文,知识点又很广,充分暴露了自己菜的事实,发现数学还是很重要的.还是要多刷题,少玩游戏. 网 ...

  4. 2019杭电多校第一场hdu6581 Vacation

    Vacation 题目传送门 update(O(n)) 看了那个O(n)的方法,感觉自己想的那个O(nlogn)的好傻,awsl. 0车最终通过停车线的时候,状态一定是某个车堵住后面的所有车(这个车也 ...

  5. 2019杭电多校第二场hdu6601 Keen On Everything But Triangle

    Keen On Everything But Triangle 题目传送门 解题思路 利用主席树求区间第k小,先求区间内最大的值,再求第二大,第三大--直到找到连续的三个数可以构成一个三角形.因为对于 ...

  6. 2019杭电多校第二场hdu6602 Longest Subarray(线段树)

    Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...

  7. Rikka with Game[技巧]----2019 杭电多校第九场:1005

      Rikka with Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Othe ...

  8. 2019杭电多校6 hdu6638 Snowy Smile(二维最大矩阵和 线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6638 题意:给你一些点的权值,让找一个矩形圈住一部分点,问圈住点的最大权值和 分析:由于是稀疏图,明显要先把x, ...

  9. 2019杭电多校三 C. Yukikaze and Demons (点分治)

    大意: 给定树, 每个点有一个十进制数位, 求有多少条路径组成的十进制数被$k$整除. 点分治, 可以参考CF715C, 转化为求$10^a x+b\equiv 0(mod\space k)$的$x$ ...

随机推荐

  1. 腾讯企业邮箱 POP3/SMTP 设置

    下午魅族MX2刷完机,原先配置的公司邮箱还要重新配置.有些地方需要改,找到了篇文章,如下: 腾讯企业邮箱支持通过客户端进行邮件管理.POP3/SMTP协议收发邮件服务器地址分别如下.接收邮件服务器:p ...

  2. ASP.NET Core - 实现自定义WebApi模型验证

    Framework时代 在Framework时代,我们一般进行参数验证的时候,以下代码是非常常见的 [HttpPost] public async Task<JsonResult> Sav ...

  3. JS 中获得根目录

    /*** * 获得根目录 * @returns */ function getRootPath() { var strFullPath = window.document.location.href; ...

  4. [译]Python中的异步IO:一个完整的演练

    原文:Async IO in Python: A Complete Walkthrough 原文作者: Brad Solomon 原文发布时间:2019年1月16日 翻译:Tacey Wong 翻译时 ...

  5. QT状态机

    首先吐槽下网上各种博主不清不楚的讲解 特别容易让新手迷惑 总体思想是这样的:首先要有一个状态机对象, 顾名思义,这玩意就是用来容纳状态的.然后调用状态机的start()函数它就会更具你的逻辑去执行相关 ...

  6. The introduction of the book American daily English notes (enlarged edition)

    After reading the book of American daily English notes written by Linkun Yang[1], I think I should a ...

  7. 算法与数据结构基础 - 排序(Sort)

    排序基础 排序方法分两大类,一类是比较排序,快速排序(Quick Sort).归并排序(Merge Sort).插入排序(Insertion Sort).选择排序(Selection Sort).希尔 ...

  8. Docker 前沿概述

    目录 Docker 前沿概述 什么是Docker? Docker的基本概念 容器(Container) -- 镜像运行时的实体 镜像(Image) -- 一个特殊的文件系统 仓库(Repository ...

  9. volatile关键字的详解-并发编程的体现

    xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! 参 ...

  10. 常用linux的命令

    常用但是容易忘记的命令 查看java项目的进程 ps -ef | grep java jps 根据进程查询端口 lsof -i | grep pid netstat -nap | grep pid p ...