树形DP: 没有上司的舞会
c++
没有上司的舞会
/* * 没有上司的舞会 * 题目描述: * Ural 大学有 N 名职员,编号为 1∼N。 * 他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。 * 每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N。 * 现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。 * 在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。 * 数组含义: * f[i][1] 表示用了, f[i][0] 表示没有用 * */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> using namespace std; const int N = 6010; int n; int h[N], ne[N], e[N], idx; int w[N]; int f[N][2]; bool st[N]; void add(int x, int y) { e[idx] = y, ne[idx] = h[x], h[x] = idx ++; } void dfs(int x) { int y; f[x][0] = 0; f[x][1] = w[x]; for (int i = h[x]; ~i; i = ne[i]) { y = e[i]; dfs(y); f[x][0] += max(f[y][0], f[y][1]); f[x][1] += f[y][0]; } } int main() { scanf("%d", &n); for (int i = 1; i <= n; i ++ ) { scanf("%d", &w[i]); } idx = 1; memset(h, -1, sizeof h); memset(ne, -1, sizeof ne); memset(st, false, sizeof st); for (int i = 1; i < n; i ++ ) { static int l, k; scanf("%d%d", &l, &k); // k is boss add(k, l); st[l] = true; } int root = -1; for (int i = 1; i <= n; i ++ ) { if (st[i] == false) { root = i; break; // 按道理说也是只有一个 } } memset(f, 0, sizeof f); // printf("root=%d\n", root); dfs(root); printf("%d\n", max(f[root][0], f[root][1])); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)