1002 没有上司的舞会 dfs 树形DP
链接:https://ac.nowcoder.com/acm/contest/25022/1002
来源:牛客网
题目描述
Ural大学有N名职员,编号为1~N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N,1≤i≤N1\leq i\leq N,1\leq i\leq N1≤i≤N,1≤i≤N。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
输入描述:
第一行一个整数N。
接下来N行,第 i 行表示 i 号职员的快乐指数Hi。
接下来N-1行,每行输入一对整数L, K,表示K是L的直接上司。
最后一行输入0,0。
输出描述:
输出最大的快乐指数。
备注:
1≤N≤6000,1\leq N\leq 6000,1≤N≤6000,
−128≤Hi≤127−128\leq H_i\leq 127−128≤Hi≤127
分析
设dp[i][2] dp[i][1] 表示以i为根节点,选择i的最大快乐指数,dp[i][0]表示以i为根节点,不选择i的最大快乐指数
状态转移:dp[i][0] += max(dp[g[i][j]][0],dp[g[i][j]][1]) 。不选择的要加上所有子节点选择或者不选择的最大值
选择的要加上所有子节点不选择的情况,最后还要加上本身的快乐指数。
//-------------------------代码---------------------------- //#define int ll const int N = 2e6+10; int n,m; int h[N]; int f[N][2]; void dfs(int p,int fa,V<int> g[]) { for(int i = 0;i<g[p].size();i++) { if(g[p][i] == fa) continue; dfs(g[p][i],p,g); f[p][0] += max(f[g[p][i]][0],f[g[p][i]][1]); f[p][1] += f[g[p][i]][0]; } f[p][1] += h[p]; } void solve() { cin>>n; V<bool> vis(n+1); V<int> g[n+1]; fo(i,1,n) cin>>h[i]; fo(i,1,n-1) { int l,k; cin>>l>>k; g[k].pb(l); vis[l] = 1; } int laji;cin>>laji>>laji; int root; fo(i,1,n) { if(vis[i] == 0) { root = i; break; } } dfs(root,-1,g); cout<<max(f[root][0],f[root][1])<<endl; } signed main(){ clapping();TLE; // int t;cin>>t;while(t -- ) solve(); // {solve(); } return 0; } /*样例区 */ //------------------------------------------------------------