【HDU6662】Acesrc and Travel(树型Dp)
大意
给出一颗树,每个点上有一个权值\(A[i]\),有两个绝顶聪明的人甲和乙。
甲乙两人一起在树上轮流走,不能走之前经过的点。(甲乙时刻在一起)
甲先手,并可以确定起点。甲想要走过的点权之和最大,乙想要权值和最小。
求最终权值和。
思路
首先有个很明显的想法就是树形Dp:
设\(F0[u]\)表示以\(u\)为根的子树内,甲先手,以\(u\)为起点的权值和。
设\(F1[u]\)表示以\(u\)为根的子树内,乙先手,以\(u\)为起点的权值和。
那么转移式就为:
\(F0[u]=Min(F1[v])+A[u]\)
\(F1[u]=Max(F0[v])+A[u]\)
其中\(v\)为\(u\)的一个儿子。
这样我们可以处理出每个点只在其子树范围走内的答案。
考虑从某个点出发,向上走形成的答案。

我们设\(TP[V]\)表示不走\(V\)的子树,甲先手,以\(V\)为起点的权值和。
那么\(TP[V]\)的更新就会有两种情况,一种是先走\(U\),然后再走\(U\)的某个儿子。

对于这种情况,甲肯定会选\(U\)的儿子中\(F0\)最大的值,即\(F1[U]\)。
但又由于\(V\)可能本身就是最大的,所以应该记录下\(F1\)的最大值与次大值进行转移。
对于另一种,就是先走\(U\),再走\(Fa\)的情况。

对于这种情况,在走到\(Fa\)时,\(B\)肯定会选择较小的那一边走。
所以就是\(Fa\)所有儿子中最小的\(F1\),即\(F0[Fa]\)与\(Fa\)向上走的情况\(TP[Fa]\)取较小值就行了。
但同理,\(U\)可能是最小的,所以记录下\(F0\)的最小值与次小值进行转移。
对于以上两种\(TP\)情况的选择由于是\(A\)选,所以取较大值。
注:在转移\(TP\)时,时刻注意为一条链的情况。
最后枚举以哪一个点为起点,取\(F0[U][0]\)与\(TP[U]\)的较小值就行了。
注意叶子节点与根的取值。
代码
细节超多,易错点主要集中在初值的赋值以及根上。
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=600005;
const long long INF=1e17;
int K,N,A[MAXN];
int son0[MAXN],son1[MAXN];
long long Ans;
long long F0[MAXN][2],F1[MAXN][2];//0:A|||||||1:B
long long TP[MAXN];
vector<int>P[MAXN];
void DFS(int u,int fa){
int Ok=0;
int size=P[u].size();
for(int i=0;i<size;i++){
int v=P[u][i];
if(v==fa)continue;
DFS(v,u);Ok=1;
if(F1[v][0]+A[u]<F0[u][0])F0[u][1]=F0[u][0],F0[u][0]=min(F0[u][0],F1[v][0]+A[u]),son0[u]=v;
else F0[u][1]=min(F0[u][1],F1[v][0]+A[u]);
if(F0[v][0]+A[u]>F1[u][0])F1[u][1]=F1[u][0],F1[u][0]=max(F1[u][0],F0[v][0]+A[u]),son1[u]=v;
else F1[u][1]=max(F1[u][1],F0[v][0]+A[u]);
}
if(!Ok)F0[u][0]=F0[u][1]=F1[u][0]=F1[u][1]=A[u];
}
void DFS2(int u,int fa){
int size=P[u].size();
for(int i=0;i<size;i++){
int v=P[u][i];
if(v==fa)continue;
long long val1=INF,val2=INF;
if(P[u].size()!=2){
if(son1[u]==v)val1=F1[u][1];
else val1=F1[u][0];
}else val1=u==1?A[u]:-INF;
if(P[fa].size()!=2){
if(son0[fa]==u)val2=F0[fa][1];
else val2=F0[fa][0];
}val2=min(val2,TP[fa]);
TP[v]=A[v]+max(val1,val2+A[u]);
DFS2(v,u);
}
}
int main(){
//freopen("data.txt","r",stdin);
//freopen("mine.txt","w",stdout);
scanf("%d",&K);
while(K--){
scanf("%d",&N);
for(int i=0;i<=N;i++){
F0[i][0]=F0[i][1]=INF;
F1[i][0]=F1[i][1]=-INF;
son0[i]=son1[i]=0;TP[i]=-INF;
P[i].clear();
}
for(int i=1;i<=N;i++)scanf("%d",&A[i]);
for(int i=1,x;i<=N;i++)scanf("%d",&x),A[i]-=x;
if(N==1){
printf("%d\n",A[1]);
continue;
}
for(int i=1,x,y;i<N;i++){
scanf("%d%d",&x,&y);
P[x].push_back(y);
P[y].push_back(x);
}Ans=-INF;P[1].push_back(0);
DFS(1,0);
if(P[1].size()!=2)TP[1]=INF;
else TP[1]=A[1];
DFS2(1,0);
Ans=F0[1][0];
for(int i=2;i<=N;i++){
if(P[i].size()==1)Ans=max(Ans,TP[i]);
else Ans=max(Ans,min(F0[i][0],TP[i]));
}
printf("%lld\n",Ans);
}
}
【HDU6662】Acesrc and Travel(树型Dp)的更多相关文章
- 2019杭电多校 hdu6662 Acesrc and Travel (树形dp
http://acm.hdu.edu.cn/showproblem.php?pid=6662 题意:有两个人在树上博弈,每个点节点有两个分数a[i]和b[i],先手先选择一个点,后手在先手选的点的相邻 ...
- 【题解】Luogu p2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat 树型dp
题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...
- 【XSY1905】【XSY2761】新访问计划 二分 树型DP
题目描述 给你一棵树,你要从\(1\)号点出发,经过这棵树的每条边至少一次,最后回到\(1\)号点,经过一条边要花费\(w_i\)的时间. 你还可以乘车,从一个点取另一个点,需要花费\(c\)的时间. ...
- 洛谷P3354 Riv河流 [IOI2005] 树型dp
正解:树型dp 解题报告: 传送门! 简要题意:有棵树,每个节点有个权值w,要求选k个节点,最大化∑dis*w,其中如果某个节点到根的路径上选了别的节点,dis指的是到达那个节点的距离 首先这个一看就 ...
- 【POJ 3140】 Contestants Division(树型dp)
id=3140">[POJ 3140] Contestants Division(树型dp) Time Limit: 2000MS Memory Limit: 65536K Tot ...
- Codeforces 581F Zublicanes and Mumocrates(树型DP)
题目链接 Round 322 Problem F 题意 给定一棵树,保证叶子结点个数为$2$(也就是度数为$1$的结点),现在要把所有的点染色(黑或白) 要求一半叶子结点的颜色为白,一半叶子结点的 ...
- ZOJ 3949 (17th 浙大校赛 B题,树型DP)
题目链接 The 17th Zhejiang University Programming Contest Problem B 题意 给定一棵树,现在要加一条连接$1$(根结点)和$x$的边,求加 ...
随机推荐
- C# .net 环境下使用rabbitmq消息队列
消息队列的地位越来越重要,几乎是面试的必问问题了,不会使用几种消息队列都显得尴尬,正好本文使用C#来带你认识rabbitmq消息队列 首先,我们要安装rabbitmq,当然,如果有现成的,也可以使用, ...
- MYSQL修改配置文件之后无法重启服务
错误:修改配置文件my.ini之后无法重启服务. 原因:以记事本方式打开my.ini文件修改完之后保存.保存之后文本编码格式为操作系统默认格式utf-8.my.ini格式要是ANSI才可以正常启动服务 ...
- linux -安装redis ,配置密码,开启远程访问
1.安装 添加epel源yum install epel-release查看yum repolist安装redis命令yum install redis查看Redis安装了哪些文件find / -na ...
- [ css ] 实现漂亮的输入框动画(借鉴自panjiachen的后台管理项目)
效果预览 HTML <div class="l-custom-input"> <input size="large" id="l-i ...
- 实验 7 : OpenDaylight 实验 —— Python 中的 REST API 调用
实验 7 : OpenDaylight 实验 -- Python 中的 REST API 调用 一.实验 目的 对 Python 调用 OpenDaylight 的 REST API 方法有初步了解. ...
- day 13 函数指针类型
(1).有以下程序: 则正确的选项是[B] (A).7 4 (B).4 10 (C).8 8 (D)10 10 分析:主要考求字符串的长度,strlen是专门求字符串长度的函数,但不包含'\0'在内. ...
- HashMap和TreeMap的内部结构
一.HashMap 1.基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hash ...
- vue学习6-if判断
<p v-if="weather=='sun'">去公园</p> <p v-else-if="weather=='s'&qu ...
- golang中json格式化自定义日期格式
go 的time.Time,在json序列化是默认 2006-01-02T15:04:05Z07:00 的格式,十分不便, encoding/json包在序列化和反序列化的时候分别调用encode.g ...
- 由浅入深,66条JavaScript面试知识点
前言 我只想面个CV工程师,面试官偏偏让我挑战造火箭工程师,加上今年这个情况更是前后两男,但再难苟且的生活还要继续,饭碗还是要继续找的.在最近的面试中我一直在总结,每次面试回来也都会复盘,下面是我这几 ...