NC51178 没有上司的舞会

题目链接

题目

题目描述

Ural大学有N名职员,编号为1~N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 Hi 给出,其中 1iN
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

输入描述

第一行一个整数N。
接下来N行,第 i 行表示 i 号职员的快乐指数Hi。
接下来N-1行,每行输入一对整数L, K,表示K是L的直接上司。
最后一行输入0,0。

输出描述

输出最大的快乐指数。

示例1

输入

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

输出

5

备注

1N6000
128Hi127

题解

知识点:树形dp。

题目要求选出独立的点,即不与别的点相邻,使得权值和最大(最大独立集)。

1 为根,设 dp[u][0/1] 表示以 u 为根节点的子树不选或选后的最大快乐度。转移方程为:

{dp[u][1]=dp[vi][1]dp[u][0]=max(dp[vi][0],dp[vi][1])

因为 u 不选的时候,子节点选不选都可以;选的时候,子节点只能不选。

时间复杂度 O(n)

空间复杂度 O(n)

代码

#include <bits/stdc++.h>
using namespace std;
int H[6007], dp[6007][10];
vector<int> g[5007];
void dfs(int u, int fa) {
for (auto v : g[u]) {
if (v == fa) continue;
dfs(v, u);
dp[u][1] += dp[v][0];
dp[u][0] += max(dp[v][0], dp[v][1]);
}
dp[u][1] += H[u];
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 1;i <= n;i++) cin >> H[i];
for (int i = 1;i <= n - 1;i++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0);
cout << max(dp[1][1], dp[1][0]) << '\n';
return 0;
}
posted @   空白菌  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示