某大学有 n 个职员,编号为 1∼N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数 ai,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。
我们设 f(i,0/1) 代表以 i 为根的子树的最优解(第二维的值为 0 代表 i 不参加舞会的情况,1 代表 i 参加舞会的情况)。
#include <iostream>using namespace std;int head[1000010 << 1], tot;long long n, sz[1000010], dep[1000010];long long f[1000010];struct node { int to, next;} e[1000010 << 1];void add(int u, int v) { // 建图 e[++tot] = {v, head[u]}; head[u] = tot;}void dfs(int u, int fa) { // 预处理dfs sz[u] = 1; dep[u] = dep[fa] + 1; for (int i = head[u]; i; i = e[i].next) { int v = e[i].to; if (v != fa) { dfs(v, u); sz[u] += sz[v]; } }}void get_ans(int u, int fa) { // 第二次dfs换根dp for (int i = head[u]; i; i = e[i].next) { int v = e[i].to; if (v != fa) { f[v] = f[u] - sz[v] * 2 + n; get_ans(v, u); } }}int main() { cin.tie(nullptr)->sync_with_stdio(false); cin >> n; int u, v; for (int i = 1; i <= n - 1; i++) { cin >> u >> v; add(u, v); add(v, u); } dfs(1, 1); for (int i = 1; i <= n; i++) f[1] += dep[i]; get_ans(1, 1); long long int ans = -1; int id; for (int i = 1; i <= n; i++) { // 统计答案 if (f[i] > ans) { ans = f[i]; id = i; } } cout << id << '\n'; return 0;}