时间复杂度
O(n)
参考文献
C++ 代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=6010;
int n;
int f[N][2]; //f[N][0]代表选当前这个点,f[N][1]代表不选当前这个点
int e[N],ne[N],idx,h[N]; //邻接表
int happy[N]; //员工的快乐指数
bool has_father[N]; //表示某个点是否有直接上司
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int dfs(int u){
f[u][1]=happy[u]; //选这个点,要先把这个点的快乐指数给算上
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
dfs(j);
f[u][1]+=f[j][0]; //当前节点选的话,他的子节点肯定就不能选
f[u][0]+=max(f[j][0],f[j][1]); //当前节点不逊,他的子节点选和不选取max
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&happy[i]);
}
memset(h,-1,sizeof h);
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
add(b,a); //b是a的直接上司
has_father[a]=true;
}
int root=1; //找没有直接上司的节点(也就是根节点)
while(has_father[root]) root++;
dfs(root);
printf("%d",max(f[root][0],f[root][1])); //选根节点和不选根节点取最大值
return 0;
}