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

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了2019杭电多校 hdu6662 Acesrc and Travel (树形dp脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

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])

向上的话,走完后对面也分为向上或向下。

向下走时,不能走当前上去的路,所以存每个点向下走的最值和次值,当最值和上去那条路得出的值相同,就换成次值。

向上走时,从上到下一路维护即可。

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

  1 #include<bITs/stdc++.h>
  2 #define ll long long 
  3 #define rep(i,a,b) for(int i=a;i<=b;i++)
  4 using namespace std;
  5 const int maxn = 1e5+5;
  6 const ll inf = 0x3f3f3f3f3f3f3f3f;
  7 ll a[maxn],b[maxn];
  8 int head[maxn],fa[maxn],to[maxn<<2],nex[maxn<<2],Now;
  9 
 10 void add(int a,int b){
 11     nex[++Now] = head[a];
 12     head[a] = Now;
 13     to[Now] = b;
 14 }
 15 
 16 ll down[maxn][2][2],up[maxn][2];
 17 bool lef[maxn];
 18 
 19 void DFs(int p){
 20     down[p][0][0] = down[p][0][1] = -inf;
 21     down[p][1][0] = down[p][1][1] = inf;
 22     lef[p] = 1;
 23     for(int i=head[p];i;i=nex[i]){
 24         if(to[i]==fa[p]) continue;
 25         lef[p] = 0;
 26         fa[to[i]] = p;
 27         dfs(to[i]);
 28         if(down[to[i]][1][0]+a[p]>=down[p][0][0]){
 29             down[p][0][1] = down[p][0][0];
 30             down[p][0][0] = down[to[i]][1][0]+a[p];
 31         }
 32         else if(down[to[i]][1][0]+a[p]>=down[p][0][1]){
 33             down[p][0][1] = down[to[i]][1][0]+a[p];
 34         }
 35         if(down[to[i]][0][0]+a[p]<=down[p][1][0]){
 36             down[p][1][1] = down[p][1][0];
 37             down[p][1][0] = down[to[i]][0][0]+a[p];
 38         }
 39         else if(down[to[i]][0][0]+a[p]<=down[p][1][1]){
 40             down[p][1][1] = down[to[i]][0][0]+a[p];
 41         }
 42     }
 43     if(lef[p]) down[p][0][0] = down[p][1][0] = a[p];
 44 }
 45 
 46 ll Abs(ll a){
 47     return a>0?a:-a;
 48 }
 49 
 50 void Dfs(int p){
 51     if(fa[p]==-1) up[p][0] = up[p][1] = inf;
 52     else {
 53         up[p][0] = inf;
 54         ll _down = down[fa[p]][1][0];
 55         if(_down==a[fa[p]]+down[p][0][0])
 56             _down = down[fa[p]][1][1];
 57         if(Abs(_down)!=inf)
 58             up[p][0] = min(up[p][0],a[p]+_down);
 59         if(fa[p]!=1)
 60             up[p][0] = min(up[p][0],a[p]+up[fa[p]][1]);
 61         if(up[p][0]==inf)
 62             up[p][0] = a[p]+a[fa[p]];
 63 
 64         up[p][1] = -inf;
 65         _down = down[fa[p]][0][0];
 66         if(_down==a[fa[p]]+down[p][1][0])
 67             _down=down[fa[p]][0][1];
 68         if(Abs(_down)!=inf)
 69             up[p][1]=max(up[p][1],a[p]+_down);
 70 
 71         if(fa[p]!=1)
 72             up[p][1]=max(up[p][1],a[p]+up[fa[p]][0]);
 73 
 74         if(up[p][1]==-inf)
 75             up[p][1]=a[p]+a[fa[p]];
 76     }
 77     for(int i=head[p];i;i=nex[i]){
 78         if(to[i]==fa[p])continue;
 79         Dfs(to[i]);
 80     }
 81 }
 82 
 83 
 84 
 85 int main(){
 86     ios::sync_with_stdio(0);
 87     cin.tie(0);
 88     cout.tie(0);
 89     int t;
 90     cin>>t;
 91     while(t--){
 92         memset(head,0,sizeof head);
 93         Now = 0;
 94         int n;
 95         cin>>n;
 96         rep(i,1,n) cin>>a[i];
 97         rep(i,n) cin>>b[i],a[i]-=b[i];
 98         rep(i,n-1){
 99             int u,v;
100             cin>>u>>v;
101             add(u,v);
102             add(v,u);
103         }
104         if(n==1){
105             cout<<a[1]<<endl;
106             continue;
107         }
108         fa[1] = -1;
109         dfs(1);
110         Dfs(1);
111         ll ans = -inf;
112         for(int i=1;i<=n;i++){
113             ll res = inf;
114             if(!lef[i]) res = min(res,down[i][1][0]);
115             if(i!=1) res = min(res,up[i][1]);
116             ans = max(ans,res);
117         }
118         cout<<ans<<endl;
119     }
120     return 0;
121 }
View Code

脚本宝典总结

以上是脚本宝典为你收集整理的2019杭电多校 hdu6662 Acesrc and Travel (树形dp全部内容,希望文章能够帮你解决2019杭电多校 hdu6662 Acesrc and Travel (树形dp所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。