一颗数中挑选若干个节点使得值最大。
挑选规则:如果挑选了该节点,那么就不能选该节点的所有直接子节点。
代码:
#include<iostream>
#include<vector>
using namespace std;
int v[10010],happy[10010];
int dp[10010][2];
int n;
vector<int>son[10010];
//dp(x):表示求出dp[x][0]和dp[x][1]
void DP(int x){
dp[x][0]=0;
dp[x][1]=happy[x];
for(int i=0;i<son[x].size();i++){
int y=son[x][i];
//dp(y)表示求出dp[y][0]和dp[y][1]
DP(y);
//当x节点不选时,取dp[y][0]和dp[y][1]的最大值
dp[x][0]+=max(dp[y][0],dp[y][1]);
//当x节点选时,只能取dp[y][0]
dp[x][1]+=dp[y][0];
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>happy[i];
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
v[x]=1;
son[y].push_back(x);
}
int root=0;
for(int i=1;i<=n;i++){
if(!v[i]){
root=i;
break;
}
}
DP(root);
cout<<max(dp[root][0],dp[root][1]);
}