F. Tree with Maximum Cost(换根)

F. Tree with Maximum Cost

 

 

 

 

 

学习博客:https://blog.csdn.net/LJD201724114126/article/details/85240762?utm_source=app

题解:换根

我们先设sum[u] 等于 以u为根的子树的∑ai (注意没有*距离),再计算以1为根的贡献值res。

这时我们要从父亲节点u向儿子节点v换根,故需要将res的值转化为以v为根的value

 

首先我们要先 res -= sum[v],因为换根之前,以v为根的子树(包括v)到原根u的深度比换根之后,到新根v的深度少了一,故减去

然后我们sum[u] -= sum[v],因为原来sum[u]表示的是以u为根的值(包括了以v为根),而这时是以v为根的,故sum[u]要减去sum[v],

res += sum[u],因为换根之前,以u为根的子树(包括u)到原根u的深度比换根之后,到新根v的深度多了一,故加上

最后sum[v]+=sum[u],因为v要成为整个树的根,而原来sum[v]不包括以u为根的节点值,故要加上。

换完之后我们再换回来。

这里巧妙的应用了换根,就是先求出任意一个根的结果,然后我们dfs,将相邻的根换一换,求出结果。

AC_Code

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 2e5+10;
 5 const int inf=0x3f3f3f3f;
 6 #define rep(i,first,last) for(ll i=first;i<=last;i++)
 7 #define dep(i,first,last) for(ll i=first;i>=last;i--)
 8 struct edge{ll to,nxt;}e[maxn<<1];
 9 ll head[maxn<<1],cnt,a[maxn],n;
10 ll ans,res,sum[maxn];
11 void addedge(ll u,ll v){ e[++cnt].to=v; e[cnt].nxt=head[u];head[u]=cnt;}
12 void dfs1(ll u,ll fa,ll h){
13     res+=(h*a[u]);
14     sum[u]=a[u];
15     for(ll i=head[u];i;i=e[i].nxt){
16         ll v=e[i].to;
17         if(v==fa) continue;
18         dfs1(v,u,h+1);
19         sum[u]+=sum[v];
20     }
21 }
22 void dfs2(ll u,ll fa){
23     ans=max(ans,res);
24     for(ll i=head[u];i;i=e[i].nxt){
25         ll v=e[i].to;
26         if( v==fa ) continue;
27 
28         res-=sum[v];
29         sum[u]-=sum[v];
30         res+=sum[u];
31         sum[v]+=sum[u];
32 
33         dfs2(v,u);
34 
35         sum[v]-=sum[u];
36         res-=sum[u];
37         sum[u]+=sum[v];
38         res+=sum[v];
39     }
40     return ;
41 }
42 signed main()
43 {
44     scanf("%lld",&n);
45     rep(i,1,n) scanf("%lld",&a[i]);
46     ll x,y;
47     rep(i,1,n-1){
48         scanf("%lld%lld",&x,&y);
49         addedge(x,y);
50         addedge(y,x);
51     }
52     dfs1(1,-1,0);
53     dfs2(1,-1);
54     printf("%lld\n",ans);
55     return 0;
56 }

 

posted @ 2020-02-22 16:04  swsyya  阅读(236)  评论(0编辑  收藏  举报

回到顶部