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); }