<L> <K>
0 0
| input | output |
|---|---|
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0 |
5 |
没有上司的年会。ural要举办场年会,请你邀请来宾。要求每位客人的直接上司不被邀请,否则会很尴尬。每位客人有一个兴趣值。要求使来宾的兴趣值之和最大。
每个人可以选择去或者不去。所以:
dp[t][0] 表示以t为最高上司的子树不安排t参加的最大兴趣值。
dp[t][1] 表示以t为最高上司的子树安排t参加的最大兴趣值。
不安排t参加的话,其直系下属可以去或者不去。dp[t][0] = sum(max(dp[ti][0], dp[ti][1]));
安排t参加的话,其直系下属均不能参加。dp[t][1] = sum(dp[ti][0]) + c[t];
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
int n;
int c[6006];
std::vector<int > v[6006];
int dp[6006][2];
void Tdp(int t) {
if(v[t].size() == 0) {
dp[t][0] = 0;
dp[t][1] = c[t];
return ;
}
for (int i=0; i<v[t].size(); i++) {
Tdp(v[t][i]);
}
for (int i=0; i<v[t].size(); i++) {
dp[t][0] += max(dp[v[t][i]][0], dp[v[t][i]][1]);
dp[t][1] += dp[v[t][i]][0];
}
dp[t][1] += c[t];
}
int main () {
cin >> n;
for (int i=1; i<=n; i++) {
cin >> c[i] ;
}
int l ,k;
int vis[6006];
memset(vis, false, sizeof(vis));
while (cin >> l >> k) {
if (l == 0 && k == 0) break;
v[k].push_back(l);
vis[l] = true;
}
int root;
for (int i=1; i<=n; i++) {
if (!vis[i]) {
root = i;
break;
}
}
Tdp(root);
cout << max(dp[root][0], dp[root][1]) <<endl;
return 0;
}原文地址:http://blog.csdn.net/xuelanghu407/article/details/43541569