【HDU6662】Acesrc and Travel【树形DP】

题目大意:给你一棵树,每个节点有一个权值,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】的更多相关文章
- 2019 Multi-University Training Contest 8 - 1006 - Acesrc and Travel - 树形dp
http://acm.hdu.edu.cn/showproblem.php?pid=6662 仿照 CC B - TREE 那道题的思路写的,差不多.也是要走路径. 像这两种必须走到叶子的路径感觉是必 ...
- 2019杭电多校 hdu6662 Acesrc and Travel (树形dp
http://acm.hdu.edu.cn/showproblem.php?pid=6662 题意:有两个人在树上博弈,每个点节点有两个分数a[i]和b[i],先手先选择一个点,后手在先手选的点的相邻 ...
- 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的距离 ...
- 寒武纪-1005 Travel(树形DP)
一.题目链接 http://aiiage.hustoj.com/problem.php?id=1005 二.题面 PDF:http://aiiage.hustoj.com/upload/file/20 ...
- 【HDU6662】Acesrc and Travel(树型Dp)
题目链接 大意 给出一颗树,每个点上有一个权值\(A[i]\),有两个绝顶聪明的人甲和乙. 甲乙两人一起在树上轮流走,不能走之前经过的点.(甲乙时刻在一起) 甲先手,并可以确定起点.甲想要走过的点权之 ...
- HDU 6662 Acesrc and Travel (换根dp)
Problem Description Acesrc is a famous tourist at Nanjing University second to none. During this sum ...
- hdu 4612 Warm up 双连通+树形dp思想
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total S ...
- HDU 6201 transaction transaction transaction(树形DP)
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- HDU - 3899 JLUCPC(树形dp求距离和)
JLUCPC Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Co ...
随机推荐
- JS-立即执行函数表达式(IIFE)
javascript 函数调用 在 javascript 中,每一个函数在被调用的时候都会创建一个执行上下文,在该函数内部定义的变量和函数只能在该函数内部被使用,而正是因为这个上下文,使得我们在调用函 ...
- 007-TreeMap、Map和Bean互转、BeanUtils.copyProperties(A,B)拷贝、URL编码解码、字符串补齐,随机字母数字串
一.转换 1.1.TreeMap 有序Map 无序有序转换 使用默认构造方法: public TreeMap(Map<? extends K, ? extends V> m) 1.2.Ma ...
- SqL语句基础之增删改查
增查删改的SQL语句,如此的实用,下面我就来简单介绍一下它简单的用法. 1.什么是SQL? SQL是用于访问和处理数据库的标准的一种计算机语言. 2.SQL可以做什么? (1)可以向数据库进行查询 ...
- datastudio 里关于with as 的用法。
datastudio 里sql 语句的写法,加入with as 语法. 这样方便查询,易于维护.以后都这样写. 优点: 1 易于维护,可以复用代码块 2 优化书写逻辑,方便查阅理解. 3 性能方面优 ...
- 腾讯开源微服务架构 Tars,高性能 RPC 开发框架
腾讯微服务架构 Tars 于今日正式开源. Tars 取名于电影“星际穿越”中的机器人,是支持多语言的高性能 RPC 开发框架和配套一体化的服务治理平台,可以帮助企业或者用户以微服务的方式快速构建稳定 ...
- ash: export: `/usr/lib/jvm/jdk1.8.0_201/lib/dt.jar': 不是有效的标识符
ash: export: `/usr/lib/jvm/jdk1.8.0_201/lib/dt.jar': 不是有效的标识符 ps: 如果有任何问题可以评论留言,我看到后会及时解答,评论或关注,您的鼓励 ...
- dfs(最长路径)
http://poj.org/problem?id=1154 LETTERS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- Numpy的基础使用
数据分析: 是把隐藏在一些看似杂乱无章的数据背后的信息提取出来,总结出所研究对象的内在规律 数据分析的三剑客: Numpy, Pandas, Matplotlib NumPy(Numerical Py ...
- Codeforces - 1176E - Cover it! - bfs
https://codeforc.es/contest/1176/problem/E 久了不写bfs了.一开始用dfs写,的确用dfs是很有问题的,一些奇怪的情况就会导致多染一些色. 注意无向图的边要 ...
- 2019牛客暑期多校训练营(第一场) - A - Equivalent Prefixes - 单调栈
A - Equivalent Prefixes - 单调栈 题意:给定两个n个元素的数组a,b,它们的前p个元素构成的数组是"等价"的,求p的最大值."等价"的 ...