题解byliuhaonan
背包型树形DP模板题目
f[0][i]表示不取i节点最大值 f[1][i]表示取i节点最大值
则f[0][i] = sum(max(f[1][son],f[0][son])) f[1][i] = sum(f[0][son])
最后答案是max(f[0][root],f[1][root])
#include <iostream>
#include <vector>
using namespace std;
int a[6010],f[2][6010]; //f[0][i]表示不取节点i最大值, f[1][i]表示取节点i最大值
vector tree[6010];
bool son[6010]; //检查某节点是不是别人的儿子,以此判断它是不是根节点
void DFS(int x) {
f[1][x] = a[x];
for(int i = 0;i < tree[x].size();i++) //遍历此节点的儿子
{
int s;
s = tree[x][i]; //儿子节点
DFS(s); //搜索儿子
f[0][x] += max(f[0][s],f[1][s]); //转移
f[1][x] += f[0][s];
}
return;
}
int main() {
int n,i,j,root;
cin>>n;
for(i = 1;i <= n;i++) cin>>a[i];
for(i = 1;i < n;i++)
{
int x,y;
cin>>x>>y;
tree[y].push_back(x); //建树
son[x] = true; //x是儿子
}
for(i = 1;i <= n;i++) if(!son[i]) //如果不是儿子
{
root = i; //就是根
break;
}
DFS(root);
cout<<max(f[0][root],f[1][root]);
return 0;
}