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. redis订阅者与发布者

    #conding=utf-8 #一.创建redis类 文件名 RedisHelper import redis # conn=redis.Redis(host='127.0.0.1')# import ...

  2. 【iOS】PrefixHeader.pch

    还不太理解,暂且记下.

  3. 基于spring的观察者模式

    简单的说,观察者模式,就类似于 广播站发送广播,和收音机的关系.多个收音机去收听同一个广播频道. 在实际的业务场景中,可以是这样的.创建订单成功后,发布事件.然后减库存.发送短信.调用微信.调用物流服 ...

  4. 今天代码中接触到了一个新的东西。js的上下自动滚动,无缝对接。

    js的上下自动滚动,无缝对接.为什么会用到这个东西呢?因为我在做公司的官网项目的修改的时候.有一个产品介绍的页面,会有很多的产品出现在,中间部分的列表里.但是又不能够使用分页.所以我就在想如果,列表数 ...

  5. JavaFX 集成 Sqlite 和 Hibernate 开发爬虫应用

    目录 [隐藏] 0.1 前言: 0.2 界面 0.3 Maven 环境 0.4 项目结构 0.5 整合 Hibernate 0.5.1 SQLiteDialect.java 数据库方言代码 0.5.2 ...

  6. PythonDay03

    ## 第三章 ### 今日内容 1.整型 2.布尔值 3.字符串 ​ 索引​ 切片​ 步长​ 字符串的方法 4.for循环 ### 1.整型 - python3:全部是整形- python2:整形,长 ...

  7. Python3 反射

    反射 python面向对象中的反射:通过字符串的形式操作对象相关的属性 hasattr(obj,name) # hasattr(obj, name) # 判断一个对象是否有指定的属性name,返回Tr ...

  8. 为什么双重检查锁模式需要 volatile ?

    双重检查锁定(Double check locked)模式经常会出现在一些框架源码中,目的是为了延迟初始化变量.这个模式还可以用来创建单例.下面来看一个 Spring 中双重检查锁定的例子. 这个例子 ...

  9. Sqlmap过waf命令tamper各脚本的适用环境

    0x00 相信很多小伙伴和我一样感同身受,站上明明有注入可是被万恶的WAF拦截了或者过滤了,这时候就需要用到SQLMAP强大的tamper了. 0x01 使用方法--tamper xxx.py apo ...

  10. Oracle 主键、联合主键的查询与创建

    --查询某个表是否有唯一主键 select cu.* from user_cons_columns cu, user_constraints au where cu.constraint_name = ...