没有上司的舞会
先给出n个人的快乐值
现在要举行舞会
现在给出n-1的关系
b是a的上司
每个人都不想和自己直系上司一起参加
求快乐值总和最大值
树形DP
用链表存储关系
然后找出根节点
从根节点开始DP
可以选择根节点参加或不参加
参加的话就先加上自己的快乐值
然后遍历子节点
遍历完后加上其子树的快乐值总和最大值
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=6011;
int h[N],idx,e[N],ne[N],happy[N],f[N][2];//f[i][j] j为1时代表选择第i个职员时其子树的最大值,0则不选择
bool has_father[N];
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
void dfs(int root){
f[root][1]=happy[root];
for(int i=h[root];~i;i=ne[i]){
int j=e[i];
dfs(j);
f[root][1]+=f[j][0];
f[root][0]+=max(f[j][0],f[j][1]);
}
}
int main(){
int n;
memset(h,-1,sizeof h);
cin>>n;
for(int i=1;i<=n;i++){
cin>>happy[i];
}
for(int i=0;i<n-1;i++){
int a,b;
cin>>a>>b;
add(b,a);
has_father[a]=1;
}
int root=1;
while(has_father[root])root++;
dfs(root);
cout<<max(f[root][0],f[root][1]);
return 0;
}