题目传送门
题意:在一个有n个结点n-1条边的树状的网络中,键盘侠a和键盘侠b一起移动,两个人轮流选择一个当前结点的相邻结点移动,每个结点至多被经过一次,当没有可以移动的结点的时候旅途结束,到达结点i后两个人获得的金币为A[i]-B[i],键盘侠a想让最终结果金币尽可能多,b想让最终结果金币尽可能少,第一轮由a任选一个结点作为起点,求最终的结果(a肯定会选择一个能使最终结果最大的结点作为起点啦~)
题解:显然为树形dp+换根。注意一些实现细节就行了
#include<bits/stdc++.h>
using namespace std;
//#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
const int maxn=1e5+5;
const ll inf=1e16;
struct edge{
int to;
int nex;
}e[maxn<<1];
int cnt,head[maxn];
ll ac,a[maxn],b[maxn],dp[2][maxn],siz[maxn];
void adde(int x,int y){
e[cnt].to=y;
e[cnt].nex=head[x];
head[x]=cnt++;
}
void dfs1(int x,int f){
dp[0][x]=-inf;
dp[1][x]=inf;
for(int i=head[x];i!=-1;i=e[i].nex){
int v=e[i].to;
if(v==f)continue;
dfs1(v,x);
dp[0][x]=max(dp[0][x],dp[1][v]);
dp[1][x]=min(dp[1][x],dp[0][v]);
}
if(dp[