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. 【Java】Class JavaLaunchHelper is implemented in both ** and **

    详细问题描述如下: objc[64179]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachin ...

  2. Java1.8新特性实战

    public class JDK8_features {private ArrayList<Integer> list; @Testpublic void test(){/*** 1.La ...

  3. python多线程详解

    目录 python多线程详解 一.线程介绍 什么是线程 为什么要使用多线程 二.线程实现 threading模块 自定义线程 守护线程 主线程等待子线程结束 多线程共享全局变量 互斥锁 递归锁 信号量 ...

  4. Apache之——多虚拟主机多站点配置的两种实现方案

    Apache中配置多主机多站点,可以通过两种方式实现: 将同一个域名的不同端口映射到不同的虚拟主机,不同端口映射到不同的站点: 将同一个端口映射成不同的域名,不同的域名映射到不同的站点. 我们只需要修 ...

  5. 我的第一个py爬虫-小白(beatifulsoup)

    一.基本上所有的python第一步都是安装.安装 我用到的第三方安装包(beatifulsoup4.re.requests).还要安装lxml 二.找个http开头的网址我找的是url="h ...

  6. 8、JAVA中的用户输入(I/0交互过程)

    这里在数组的学习中用到了用户输入,也就是交互模式,日常的数据,不可能每一次都是程序员定义好的,终究需要用户与程序之间进行交互,机器等待用户输入,用户通过键盘输入所需数据(数据包括,字符,字串,数值等) ...

  7. mysql优化---订单查询优化(1):视图优化+索引创建

    订单的表结构采用了垂直分表的策略,将订单相关的不同模块的字段维护在不同表中 在订单处理这个页面,需要查询各种维度, 因此为了方便查询创建了v_sale_order视图(老版本) drop view v ...

  8. 在linux系统下安装mysql详解,以及远程调用连接不上mysql的解决方法。

    步骤: 1)查看CentOS自带的mysql 输入 rpm -qa | grep mysql 2)将自带的mysql卸载 3)上传Mysql的安装包到linux 4)安装mysql的依赖(不是必须) ...

  9. Reactive 漫谈

    目录 概念 面向流设计 异步化 响应式宣言 参考文档 概念 Reactive Programming(响应式编程)已经不是一个新东西了. 关于 Reactive 其实是一个泛化的概念,由于很抽象,一些 ...

  10. AQS源码解析(一)-AtomicBoolean源码解析

    基本类: AtomicInteger AtomicLong AtomicBoolean 数组类型: AtomicIntegerArray AtomicLongArray AtomicReference ...