#include<bits/stdc++.h>
#include <iostream>
using namespace std;
//树状动态规划
#define maxn 6666
int tree[maxn][2];
//tree[i][1] 表示以i为根节点,i参加的最大快乐值
//tree[i][0] 表示以i为根节点,i不来参加的最大值
vector<int> boss[maxn];//表示第i个人有哪几个儿子
int h[maxn];//用来存储每个人的欢乐值
int temp[maxn];//用来记录哪几个人有老板,没有老板的那个人就是根节点boss
void dfs(int x)
{
//树从最底层开始
tree[x][0]=0;//x员工不来值为0
tree[x][1]=h[x];//x员工来就增加其欢乐值
//广度优先搜索
for(int i=0;i<boss[x].size();i++)
{
int temp=boss[x][i];
dfs(temp);//一直深度优先初始化完最底层
tree[x][0]+=max(tree[temp][1],tree[temp][0]);//上司不来儿子可来可不来,加上二者取最大值(因为欢乐值可能为负数)
tree[x][1]+=tree[temp][0];//上司来就加上儿子不来的最大欢乐值
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&h[i]);
}
int father,son;
for(int i=1;i<=n-1;i++)
{
scanf("%d%d",&son,&father);
boss[father].push_back(son);
temp[son]=1;
}
//找根节点
int root;
for(int i=1;i<=n;i++)
{
if(!temp[i]) root=i;
}
dfs(root);
//最后肯定是根节点来或不来其中一个最大
cout<<max(tree[root][0],tree[root][1])<<endl;
return 0;
}
树状动态规划 P1352 没有上司的舞会
最新推荐文章于 2024-07-15 13:32:43 发布