没有上司的舞会

1 minute read

没有上司的舞会

题目描述

某大学有 $n$ 个职员,编号为 $1\ldots n$。

他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。

现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数 $r_i$,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。

所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入格式

输入的第一行是一个整数 $n$。

第 $2$ 到第 $(n + 1)$ 行,每行一个整数,第 $(i+1)$ 行的整数表示 $i$ 号职员的快乐指数 $r_i$。

第 $(n + 2)$ 到第 $2n$ 行,每行输入一对整数 $l, k$,代表 $k$ 是 $l$ 的直接上司。

输出格式

输出一行一个整数代表最大的快乐指数。

样例 #1

样例输入 #1

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

样例输出 #1

5

提示

数据规模与约定

对于 $100\%$ 的数据,保证 $1\leq n \leq 6 \times 10^3$,$-128 \leq r_i\leq 127$,$1 \leq l, k \leq n$,且给出的关系一定是一棵树。

Analysis

本题实质上是一个树形dp的问题。设 f[i][j] 表示选择指定节点i后,获得的最大价值,其中j分为两种情况,不选,对于我们来说,只需要枚举所有可能的情况,求得最大值即可, 具体情况如下:

  1. 当前节点 i 选择, 则价值为:

    \[f[i][1] = v[i] + \sum_{j=1}^{k} f[j][0] \hspace{1cm} j \in g[i]\;,\; k ==len(g[i])\]
  2. 当前节点i 不选择, 则价值为 :

    \[f[i][0] = \sum_{j=1}^{k} (min(f[j][0], f[j][1])) \hspace{1cm} j \in g[i]\;,\; k ==len(g[i])\]
  3. 最后整棵树的最大价值为:

    \[maxval = max(f[root][0], f[root][1])\]

Solutions

1. Monotanic-Stack

from collections import defaultdict
import sys
sys.setrecursionlimit(10**9)
n = int(input())
happiness = [int(input()) for _ in range(n)]
boss = [list(map(int, input().split()))for _ in range(n-1)]

graph = defaultdict(list)
in_degree = [0] * n
for u, v in boss:
    graph[v].append(u)
    in_degree[u - 1] += 1

def dfs(root):
    choose = happiness[root - 1]
    not_choose = 0
    for child in graph[root]:
        child_not_choose, child_choose = dfs(child)
        choose += child_not_choose
        not_choose += max(child_not_choose, child_choose)
    return [not_choose, choose]

for i, num in enumerate(in_degree):
    if num == 0:
        root = i + 1
ans= max(dfs(root))
print(ans)

Input:

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

output:

5

Complexity

  • Time complexity: ( O(2^n) ), where ( n ) is the length of the array.
  • Space complexity: ( O(2^n) ), where ( n) is the length of the array.

Comments