题目描述
Ural大学有N名职员,编号为1~N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N1≤i≤N。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
输入格式
第一行一个整数N。
接下来N行,第 i 行表示 i 号职员的快乐指数HiHi。
接下来N-1行,每行输入一对整数L, K,表示K是L的直接上司。
输出格式
输出最大的快乐指数。
数据范围
1 ≤ N ≤ 6000,
−128 ≤ Hi ≤ 127
输入样例:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
输出样例:
5
难度:简单 |
时/空限制:1s / 64MB |
来源:《算法竞赛进阶指南》, 模板题 |
题目分析:
这题其实和大盗阿福 没差别,只是线性结构变成树形结构,只要O(n)找下根节点,然后从根节点到叶节点dfs一下即可
扫描二维码关注公众号,回复:
10548635 查看本文章
代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 6e3 + 10;
int f[N][2];
int h[N], st[N];
int head[N], nex[N], edge[N], tot;
void add(int u, int v){
edge[++ tot] = v;
nex[tot] = head[u];
head[u] = tot;
}
void dfs(int u){
f[u][1] = h[u];
for (int i = head[u]; ~i; i = nex[i]){
int v = edge[i];
dfs(v);
f[u][0] += max(f[v][0], f[v][1]);
f[u][1] += f[v][0];
}
}
int main()
{
memset(head, -1, sizeof(head));
int n;
cin >> n;
for (int i = 1; i <= n; ++ i) cin >> h[i];
int u, v;
for (int i = 1; i < n; ++ i){
cin >> u >> v;
add(v, u);
st[u] = 1;
}
int root = 1;
while (st[root]) ++ root;
dfs(root);
cout << max(f[root][0], f[root][1]) << endl;
return 0;
}