acwing 285. 没有上司的舞会

简介: acwing 285. 没有上司的舞会

活动 - AcWing

树形dp

f[i][0/1] 表示以i为根节点的子树当选择i或者不选择i时的最大快乐值

对于f[i][1] 也就是我们选择 i 所以进入dfs 我们先将w[i] 加入 f[i][1] 中,然后,我们对于 i 各个孩子,我们都不能取 (因为不能有直接上司),所以我们加 f[j][0](也就是说我们加上不取 j 的时候最大快乐值)

对于f[i][0] 也就是我们不选择 i 所以我们可以 1.取子树 f[j][1]  2 . 不取子树 f[j][0] , 两者之间取最大值

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
 
using namespace std ;
const int N = 6010 ;
 
vector<int> tree[N] ;//存邻接表 
int f[N][2] ;//表示以i为结点的子树,当取i 或着 不取i时 的最大快乐值 
int has_fa[N] ;//记录每一个点是否有父节点,方便找根节点 
int n ;
int w[N] ;//每一个节点的快乐值 
void dfs(int u){
  f[u][1] = w[u] ;
  for(int i = 0 ; i < tree[u].size() ; i ++){
    int j = tree[u][i] ;
    dfs(j) ;
    f[u][1] += f[j][0] ;
    f[u][0] += max(f[j][0],f[j][1]) ; 
  }
}
int main(){
  cin >> n ;
  for(int i = 1 ; i <= n ;i ++) cin >> w[i] ;
  for(int i = 1 ; i < n ;i ++){
    int a , b ; cin >> a >> b ;
    tree[b].push_back(a) ;
    has_fa[a] = 1 ;
  }
  int root = 1 ;
  while(has_fa[root]) root ++ ;
  dfs(root) ;
  printf("%d\n",max(f[root][0],f[root][1])) ;
  return 0 ;
}
目录
相关文章
|
3天前
acwing 1010 拦截导弹
acwing 1010 拦截导弹
10 1
AcWing 1265. 数星星(每日一题)
AcWing 1265. 数星星(每日一题)
|
3天前
acwing 898 数字三角形
acwing 898 数字三角形
13 2
|
2天前
acwing 1017 怪盗基德的滑翔翼
acwing 1017 怪盗基德的滑翔翼
4 0
|
2天前
acwing 1012 友好城市
acwing 1012 友好城市
5 0
|
2天前
acwing 1014 登山
acwing 1014 登山
4 0
AcWing 562. 壁画(每日一题)
AcWing 562. 壁画(每日一题)
|
5月前
|
人工智能
acwing 5478. 分班
acwing 5478. 分班