树形DP
没有上司的舞会
状态表示
f[u][0] : 所有从以u为根的子树中选择,并且不选择这个点的方案
f[u][1]: 所有从以u为根的子树中选择,并且选择这个点的方案
状态计算
const int N = 6005; vector<int>v[N]; //邻接表 int happy[N]; //快乐值 bool has_father[N]; //找到根节点 int f[N][2]; void dfs(int u) { f[u][1] = happy[u]; for (int i = 0; i < v[u].size();++i) { int j = v[u][i]; //当前节点的子节点 dfs(j); // 先递归 后计算 f[u][0] += max(f[j][0], f[j][1]); // 状态转移 f[u][1] += f[j][0]; // 状态转移 } } int main() { int n;cin >> n; for (int i = 1; i <= n;++i)cin >> happy[i]; for (int i = 1;i < n;++i) { //读入树 int a, b;cin >> a >> b; v[b].push_back(a); has_father[a] = true; } int root = 1; while (has_father[root])++root; //找到根节点 dfs(root); printf("%d\n", max(f[root][0], f[root][1])); }