luogu P1352ybtoj 树形DP课堂过关 例题1树上求和 & 没有上司的舞会

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1352ybtoj 树形DP课堂过关 例题1树上求和 & 没有上司的舞会相关的知识,希望对你有一定的参考价值。

【例题1】树上求和 & 没有上司的舞会


Link

【ybtoj】【树形DP课堂过关】【例题1】树上求和
【luogu】【P1352】 没有上司的舞会
题面//因为不知道侵不侵权所以就是题面是私密的,有账号的直接看转送门就可了


题目大意

给出一颗树,每个结点都有一个权值 ,请选择一些结点

  1. 被选结点的权值和最大
  2. 被选结点之间不能存在父子关系,即选了父亲不能选儿子,选了儿子不能选父亲

解题思路

虽然…写过,但是…要水博客

对于每个节点只有选([1])和不选([0])两种方案

  • f[当前节点 i i i][0] = f[i][1] + max(f[子节点 j j j][0],f[j][1])
    当前节点不选,儿子选不选都可以
  • f[i][1] = f[i][1] + f[j][0]
    当前节点选中,儿子不可以选

Code

#include <iostream>
#include <cstdio>

using namespace std;

struct DT{
	int y, next;
}a[6100]; 
int n, l, k, num, ans;
int s[6100], head[6100], t[6100], f[6100][2];

void dfs(int x) {
	f[x][1] = s[x];
	for(int i = head[x]; i; i = a[i].next) {
		dfs(a[i].y);
		f[x][0] = f[x][0] + max(f[a[i].y][0], f[a[i].y][1]);
		f[x][1] = f[x][1] + f[a[i].y][0];
	}
}

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
		scanf("%d", &s[i]);
	for(int i = 1; i < n; i++) {
		scanf("%d %d", &l, &k);
		t[l]++;
		a[++num] = (DT){l, head[k]};
		head[k] = num;
	}
	for(int i = 1; i <= n; i++) {
		if(!t[i]) dfs(i);
		ans = max(ans, max(f[i][0], f[i][1]));
	}
	printf("%d", ans);
} 

以上是关于luogu P1352ybtoj 树形DP课堂过关 例题1树上求和 & 没有上司的舞会的主要内容,如果未能解决你的问题,请参考以下文章

luogu UVA10559 ybtoj 区间DP课堂过关 例题3消除木块 & 方块消除 Blocks

ybtoj 树形DP课堂过关例题2结点覆盖

luogu P4170ybtoj 区间DP课堂过关 例题2木板涂色 & [CQOI2007]涂色

luogu P1880ybtoj 区间DP课堂过关 例题1石子合并 & [NOI1995] 石子合并

luogu P1048ybtoj背包问题课堂过关DP例题1采药问题 &NOIP2005 普及组采药

luogu P5020ybtoj背包问题课堂过关DP例题2货币系统 & NOIP2018 提高组货币系统