CF1092F Tree with Maximum Cost(简单树形DP)

题意:

给出一棵树,答案的计算公式是所有节点的自身权值乘上它们到根节点的距离。

请你选择合适的根节点,使得答案最大化。

题解:

简单树形DP,思考一下从父节点到子节点、子节点到父节点的状态的转移。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int n;
ll a[maxn];
vector<int> g[maxn];
ll h[maxn];
ll size[maxn];
ll d[maxn];//一个节点的所有子树节点距离自己的距离和
ll sum[maxn];
ll num;
void dfs (int u,int f) {
    d[u]=0;
    h[u]=h[f]+1;
    size[u]=a[u];
    for (int v:g[u]) {
        if (v==f) continue;
        dfs(v,u);
        d[u]=d[u]+d[v]+size[v];
        size[u]+=size[v];
    }
} 
void dfs1 (int u,int f) {
    if (f)d[u]=d[f]-size[u]+(num-size[u]);
    for (int v:g[u]) {
        if (v==f) continue;
        dfs1(v,u);
    }
} 
int main () {
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lld",a+i),num+=a[i];
    for (int i=1;i<n;i++) {
        int x,y;
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs(1,0);dfs1(1,0);
    ll ans=0;
    //for (int i=1;i<=n;i++) printf("%lld ",d[i]);
    for (int i=1;i<=n;i++) ans=max(ans,d[i]);
    printf("%lld\n",ans);
}

 

posted @ 2020-08-18 20:03  zlc0405  阅读(116)  评论(0编辑  收藏  举报