老师让复习二叉树,我旁边的zjy大佬直接给了我一堆树的题,然后就有了这道树形DP的题 还没学会爬就开始跑了???
题目也非常非常清楚地告诉了你,这道题是树啊!!!每个职员都有一个快乐指数,如果职员直接上司(父亲)去了,那职员就不能去 真实,求怎么样才能最快乐(???)
既然是树,首先就要找到他的根节点,对于这道题来说还是很好找的,因为输入了l,k,那么就对l标记为true(他是个职员),那么这样最后肯定就只会剩下一个人没有标记,就是最大的上司了
然后开始搞怎么样最快乐,搜索肯定是一种方法,但是DP也有点显而易见,给一个f[6005][2],第二维存储两个状态,0代表不让他去,1表示让他去。那么对于他的员工,就也有对应的情况:当上司的状态为1,那职员的状态都为0;当上司的状态为0时,应该取max(f[职员][0],f[职员][1]),取最大值是因为题目中通说,一个职员的快乐值可以为负 生活不易,职员叹气,最后的答案就是最大的上司去和不去的最大值就可以了
#include<bits/stdc++.h>
using namespace std;
int n;
int r[6005];
vector<int> tree[6005];
int f[6005][2];
bool v[6005];
void dp(int x){
f[x][0]=0;
f[x][1]=r[x];
for(int i=0;i<tree[x].size();i++){
int y=tree[x][i];
dp(y);
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}
int main(){
scanf("%d",&n);
for(register int i=1;i<=n;i++) scanf("%d",&r[i]);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
tree[y].push_back(x);
v[x]=true;
}
int root;
for(int i=1;i<=n;i++){
if(v[i]==false){
root=i;
break;
}
}
dp(root);
cout<<max(f[root][0],f[root][1]);
return 0;
}