一:没有上司的舞会
Ural大学有N名职员,编号为1~N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N1≤i≤N。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
输入格式
第一行一个整数N。
接下来N行,第 i 行表示 i 号职员的快乐指数HiHi。
接下来N-1行,每行输入一对整数L, K,表示K是L的直接上司。
输出格式
输出最大的快乐指数。
数据范围
1≤N≤60001≤N≤6000,
−128≤Hi≤127−128≤Hi≤127
输入样例:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
输出样例:
5
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 6010; 5 6 vector<int> g[N]; 7 int val[N]; 8 int memo[N][2];//0 代表不选根节点 1 代表选根节点 9 bool fa[N];//用来找到根 10 11 int dfs(int root, int select){ 12 if(memo[root][select] != -1) return memo[root][select]; 13 int ans = 0; 14 if(select == 0) 15 for(auto t : g[root]) 16 ans += max(dfs(t, 0), dfs(t, 1)); 17 else{ 18 ans += val[root]; 19 for(auto t : g[root]) 20 ans += dfs(t, 0); 21 } 22 return memo[root][select] = ans; 23 } 24 25 int main(){ 26 int n;cin >> n; 27 for(int i = 1;i <= n;++i) cin >> val[i]; 28 for(int i = 1;i <= n-1;++i){ 29 int a, b; cin >> a >> b; 30 g[b].push_back(a); 31 fa[a] = true; 32 } 33 int root = 1; 34 while(fa[root]) ++root; 35 memset(memo, -1, sizeof memo); 36 cout << max(dfs(root, 0), dfs(root, 1)) << endl; 37 return 0; 38 }