原题:
思路:
经典树形DP
借此题讲解一下树形DP
顾名思义,树形DP以「子树」作为单位进行DP
由于这个性质,DFS成了实现的最好选择
先DFS求出子问题,随后得出当前规模答案。
详见代码
这个还可以用拓扑排序做
代码:
#include <bits/stdc++.h> using namespace std; int n,a[6050]; int v_[6050]; int f[6050][6050]; struct edge { int u,v,nxt; }E[6050]; int h[6050]; int cnt; void add_edge(int u,int v) { E[cnt++].u=u; E[cnt].v=v; E[cnt].nxt=h[u]; h[u]=cnt; } void dp(int x) { f[x][0]=0; f[x][1]=a[x]; for(int i=h[x];i;i=E[i].nxt) { dp(E[i].v); f[x][0]+=max(f[E[i].v][0],f[E[i].v][1]); f[x][1]+=f[E[i].v][0]; } } int main() { cin >> n; for(int i=1;i<=n;i++) cin >> a[i]; for(int i=1;i<=n-1;i++) { int u,v; cin >> u >> v; add_edge(v,u); v_[u]=1; } int rt; for(int i=1;i<=n;i++) if(!v_[i]) { rt=i; break; } dp(rt); cout << max(f[rt][0],f[rt][1]) << endl; return 0; }