题目大意:给你一棵树,每个节点有一个权值,Alice和Bob进行博弈,起点由Alice确定,确定后交替选择下一个点,Alice目标是最终值尽可能大,Bob目标是尽可能小

题解:很明显是树形DP,那么考虑如何dp

设F[i][0/1]表示第i个点先手选/后手选的答案

那么不难想到

F[i][0]=max(F[j][1])+v[i]

F[i][1]=min(F[j][0])+v[i]

一次以1为根进行dfs可以求出选择1为根时的答案,此时考虑换根

换根时将换根前的所有状态保存下来,dfs下去之后求出其子树答案后将状态复原

换根时有两种情况,1、原根的答案是新根推过来的。2、原根的答案不是从新根推过来的

对于第二种情况很简单,我们只需要把原根当做新根的子树然后进行转移即可

考虑第一种情况,将原根变为儿子之后,其F值由除新根之外的所有儿子转移而来

于是很容易想到在原有保存最大值(最小值)的基础上再保存次大值(次小值),这样就可以O(1)更新原根的答案了

更新完后就和第二种情况一样了

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#define ll long long
#define INF 1e18
using namespace std;
int T,n;
ll v[],f[][];
ll mx[][],mn[][];
ll ans;
int mxbh[],mnbh[];
struct node
{
int x,y;
}tr[*];
int hd[],nxt[*],rn;
void build(int x,int y){tr[++rn]=(node){x,y};nxt[rn]=hd[x];hd[x]=rn;}
void init()
{
rn=;
memset(f,,sizeof(f));
memset(hd,,sizeof(hd));
memset(nxt,,sizeof(nxt));
}
void dfs(int now,int last)
{
int t1=hd[now],t2;
mx[now][]=mx[now][]=-INF;
mn[now][]=mn[now][]=INF;
mxbh[now]=;mnbh[now]=;
while(t1)
{
t2=tr[t1].y;
if(t2!=last)
{
dfs(t2,now);
if(f[t2][]>=mx[now][]){mx[now][]=mx[now][];mx[now][]=f[t2][];mxbh[now]=t2;}
else if(f[t2][]>mx[now][])mx[now][]=f[t2][];
if(f[t2][]<=mn[now][]){mn[now][]=mn[now][];mn[now][]=f[t2][];mnbh[now]=t2;}
else if(f[t2][]<mn[now][])mn[now][]=f[t2][];
}
t1=nxt[t1];
}
if(mx[now][]==-INF)mx[now][]=;
if(mn[now][]==INF)mn[now][]=;
//printf("%d:%lld %lld %lld\n",now,mx[now][0],mn[now][0],v[now]);
f[now][]=mx[now][]+v[now];
f[now][]=mn[now][]+v[now];
//printf("%d %lld %lld %lld\n",now,f[now][1],max1,v[now]);
}
void dfs2(int now,int last)
{
ans=max(ans,f[now][]);
//printf(" %d\n",now);
//for(int i=1;i<=n;i++)printf("%lld %lld:%d %d\n",f[i][0],f[i][1],mxbh[i],mnbh[i]);
//printf(" %lld %lld|%lld %lld\n",mx[now][0],mx[now][1],mn[now][0],mn[now][1]);
//printf("\n");
int t1=hd[now],t2;
ll fi0,fi1,fj0,fj1,tv,mxj0,mxj1,mnj0,mnj1;
int mxbhi,mxbhj,mnbhi,mnbhj;
while(t1)
{
t2=tr[t1].y;
if(t2!=last)
{
fi0=f[now][];fi1=f[now][];
fj0=f[t2][];fj1=f[t2][];
mxbhi=mxbh[now];mnbhi=mnbh[now];
mxbhj=mxbh[t2];mnbhj=mnbh[t2];
if(mxbh[now]==t2)
{
tv=v[now];
if(mx[now][]!=-INF)tv+=mx[now][];
f[now][]=tv;
}
if(mnbh[now]==t2)
{
tv=v[now];
if(mn[now][]!=INF)tv+=mn[now][];
f[now][]=tv;
}
mxj0=mx[t2][];mxj1=mx[t2][];
mnj0=mn[t2][];mnj1=mn[t2][];
if(mxbhj==)mx[t2][]=-INF;
if(mnbhj==)mn[t2][]=INF;
if(f[now][]>=mx[t2][]){mx[t2][]=mx[t2][];mx[t2][]=f[now][];mxbh[t2]=now;}
else if(f[now][]>mx[t2][])mx[t2][]=f[now][];
if(f[now][]<=mn[t2][]){mn[t2][]=mn[t2][];mn[t2][]=f[now][];mnbh[t2]=now;}
else if(f[now][]<mn[t2][])mn[t2][]=f[now][];
f[t2][]=mx[t2][]+v[t2];
f[t2][]=mn[t2][]+v[t2];
dfs2(t2,now);
f[now][]=fi0;f[now][]=fi1;
f[t2][]=fj0;f[t2][]=fj1;
mx[t2][]=mxj0;mx[t2][]=mxj1;
mn[t2][]=mnj0;mn[t2][]=mnj1;
mxbh[now]=mxbhi;mnbh[now]=mnbhi;
mxbh[t2]=mxbhj;mnbh[t2]=mnbhj;
}
t1=nxt[t1];
}
}
int main()
{
scanf("%d",&T);
int a,b;
while(T--)
{
init();
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%lld",&v[i]);
for(int i=;i<=n;i++){scanf("%d",&a);v[i]-=a;}
for(int i=;i<n;i++)
{
scanf("%d%d",&a,&b);
build(a,b);build(b,a);
}
memset(f,,sizeof(f));
dfs(,);
ans=-INF;
//for(int i=1;i<=n;i++)printf("%lld %lld/%lld %lld:%d %d %lld %lld\n",mx[i][0],mx[i][1],mn[i][0],mn[i][1],mxbh[i],mnbh[i],f[i][0],f[i][1]);
dfs2(,);
//ans=-INF;
//for(int i=1;i<=n;i++)ans=max(ans,f[i][1]);
//for(int i=1;i<=n;i++)printf("%lld %lld:%d %d\n",f[i][0],f[i][1],mxbh[i],mnbh[i]);
printf("%lld\n",ans);
}
return ;
}

心得:典型的树形DP的题目,换根时的操作还需要更多练习熟练

【HDU6662】Acesrc and Travel【树形DP】的更多相关文章

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

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

  2. 2019杭电多校 hdu6662 Acesrc and Travel (树形dp

    http://acm.hdu.edu.cn/showproblem.php?pid=6662 题意:有两个人在树上博弈,每个点节点有两个分数a[i]和b[i],先手先选择一个点,后手在先手选的点的相邻 ...

  3. BZOJ.1576.[Usaco2009 Jan]安全路经Travel(树形DP 并查集)

    题目链接 BZOJ 洛谷 先求最短路树.考虑每一条非树边(u,v,len),设w=LCA(u,v),这条边会对w->v上的点x(x!=w)有dis[u]+dis[v]-dis[x]+len的距离 ...

  4. 寒武纪-1005 Travel(树形DP)

    一.题目链接 http://aiiage.hustoj.com/problem.php?id=1005 二.题面 PDF:http://aiiage.hustoj.com/upload/file/20 ...

  5. 【HDU6662】Acesrc and Travel(树型Dp)

    题目链接 大意 给出一颗树,每个点上有一个权值\(A[i]\),有两个绝顶聪明的人甲和乙. 甲乙两人一起在树上轮流走,不能走之前经过的点.(甲乙时刻在一起) 甲先手,并可以确定起点.甲想要走过的点权之 ...

  6. HDU 6662 Acesrc and Travel (换根dp)

    Problem Description Acesrc is a famous tourist at Nanjing University second to none. During this sum ...

  7. hdu 4612 Warm up 双连通+树形dp思想

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

  8. HDU 6201 transaction transaction transaction(树形DP)

    transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/1 ...

  9. HDU - 3899 JLUCPC(树形dp求距离和)

    JLUCPC Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Co ...

随机推荐

  1. 用notepad++ 打造轻量级Java编译器

    http://blog.163.com/jackie_howe/blog/static/19949134720125591752396/ 用notepad++ 打造轻量级Java编译器 2012-06 ...

  2. Nginx 实现全站 HTTPS(基于 Let's Encrypt 的免费通配符证书)

    单域名证书的生成可以 参考这里. acme.sh 项目中文文档 Let's Encrypt 在 18 年 1 月份推出了 ACME v2,支持通配符域名证书,对小网站.个人站长的友好度进一步增加. 常 ...

  3. WebService登陆验证四种方式

    在这个WEB API横行的时代,讲WEB Service技术却实显得有些过时了,过时的技术并不代表无用武之地,有些地方也还是可以继续用他的,我之所以会讲解WEB Service,源于我最近面试时被问到 ...

  4. waf学习

    参考文章: http://drops.xmd5.com/static/drops/tips-7883.html waf种类 云waf 传统安全厂商的硬件waf以及一直存在ips,ids设备 主机防护软 ...

  5. 进程池Pool的简单使用,同步异步的区别

    #进程池 """ 当需要创建子进程数量不多的时候,可以直接利用multiprocessing 中的Process动态生成多个进程,但是如果上百甚至上千个任务, " ...

  6. Hibernate异常:IllegalArgumentException

    异常信息: java.lang.IllegalArgumentException: attempt to create delete event with null entity at org.hib ...

  7. kmp(前缀出现次数next应用)

    http://acm.hdu.edu.cn/showproblem.php?pid=3336 Count the string Time Limit: 2000/1000 MS (Java/Other ...

  8. python常用模块----re模块

    正则表达式就是匹配字符串内容的一种规则. 字符组: [0123456789] 表示0-9这个范围内的任意一个数字都可以与之匹配,简写为[0-9] [a-z] 表示匹配所有的小写字母 [A-Z] 表示匹 ...

  9. redis缓存架构-03-redis下的replication以及master+slave

    1.master和slave的读写分离(水平扩容支持读高并发) 2.master主从复制流程 master开始复制给slave前的认证流程 master向slave复制流程 2.1 无磁盘化复制配置 ...

  10. vue 当前页跳转并强制刷新

    watch: { '$route'(to, from) { this.$router.go(0); } }, this.$router.push({ path: '/dashboard/XXZX?' ...