C. Uncle Bogdan and Country Happiness( 树型递推(其实不能叫dp吧?) )

每个人从1节点走回自己家

一定是前一段路的心情好(可能前一段路长为0),后一段路心情差

我们的难点在哪里?

在于有很多个人,我们不能确定每个人在哪个节点心情开始变差的

但其实我们是可以大概确定的

Ⅰ . 考 虑 叶 子 节 点 \color{Red}Ⅰ.考虑叶子节点 .

对 于 一 个 叶 子 节 点 w 来 说 对于一个叶子节点w来说 w

能 到 达 w 的 都 是 家 在 w 的 , 设 这 些 人 到 达 时 有 x 个 人 心 情 好 , y 个 人 心 情 产 能到达w的都是家在w的,设这些人到达时有x个人心情好,y个人心情产 ww,x,y

{ x + y = p w x − y = h w \left\{ \begin{aligned} x+y=p_w \\ x-y=h_w \\ \end{aligned} \right. {x+y=pwxy=hw

所 以 x 是 ( p w + h w ) / 2 ,   y 是 p w − x 所以x是(p_w+h_w)/2,\ y是p_w-x x(pw+hw)/2, ypwx

其 中 ( p w + h w ) 应 该 是 偶 数 其中(p_w+h_w)应该是偶数 (pw+hw)


Ⅱ . 考 虑 非 叶 子 节 点 k \color{Red}Ⅱ.考虑非叶子节点k .k

这一步其实就是由叶子节点往上推的

k 的 最 少 开 心 人 数 是 所 有 子 节 点 开 心 人 数 相 加 , 记 作 d p [ k ] [ 1 ] k的最少开心人数是所有子节点开心人数相加,记作dp[k][1] k,dp[k][1]

k 的 最 大 不 开 心 人 数 是 所 有 子 节 点 不 开 心 人 数 和 + p k , 记 作 d p [ k ] [ 2 ] k的最大不开心人数是所有子节点不开心人数和+p_k,记作dp[k][2] k+pk,dp[k][2]

至 于 为 啥 加 p k . . . . . . 因 为 这 p k 个 人 在 k 节 点 可 能 开 心 , 也 可 能 不 开 心 , 若 都 不 开 心 那 么 人 数 就 最 大 嘛 . . . 至于为啥加p_k......因为这p_k个人在k节点可能开心,也可能不开心,若都不开心那么人数就最大嘛... pk......pkk,,...

那 么 当 前 经 过 这 个 点 的 人 是 s u m n = d p [ k ] [ 1 ] + d p [ k ] [ 2 ] 那么当前经过这个点的人是sumn=dp[k][1]+dp[k][2] sumn=dp[k][1]+dp[k][2]

由 Ⅰ 知 s u m n 必 须 是 偶 数 , 那 么 可 以 解 得 k 节 点 有 x 人 心 情 好 , y 人 心 情 差 由Ⅰ知sumn必须是偶数,那么可以解得k节点有x人心情好,y人心情差 sumn,kx,y

这 样 我 们 解 得 x = ( s u m n + h k ) / 2 , y = s u m n − x 这样我们解得x=(sumn+h_k)/2,y=sumn-x x=(sumn+hk)/2,y=sumnx

我再重申一下 d p [ k ] [ 1 ] dp[k][1] dp[k][1]是最少开心得人数

因 为 子 节 点 开 心 得 人 在 上 一 个 节 点 一 定 开 心 因为子节点开心得人在上一个节点一定开心 (只能由开心->不开心)

但 是 可 能 还 存 在 一 些 人 在 k 节 点 开 心 , 但 是 跑 到 子 节 点 就 不 开 心 了 但是可能还存在一些人在k节点开心,但是跑到子节点就不开心了 k,

所 以 这 里 应 该 满 足 w > = d p [ k ] [ 1 ] 所以这里应该满足w>=dp[k][1] w>=dp[k][1]

判 断 完 之 后 , 由 于 k 点 的 开 心 , 不 开 心 人 数 被 计 算 出 来 了 , 那 么 判断完之后,由于k点的开心,不开心人数被计算出来了,那么 ,k,,

d p [ k ] [ 1 ] = x , d p [ k ] [ 2 ] = y , 然 后 继 续 向 上 推 dp[k][1]=x,dp[k][2]=y,然后继续向上推 dp[k][1]=x,dp[k][2]=y,


然 后 对 任 意 一 个 节 点 w 满 足 经 过 w 的 总 人 数 > a b s ( h w ) , 比 较 显 然 然后对任意一个节点w满足经过w的总人数>abs(h_w),比较显然 ww>abs(hw),

然 后 ? 然 后 就 开 始 d f s 啊 ! ! \color{green}然后?然后就开始dfs啊!! ?dfs!!

觉得我讲的不好可以在评论区骂我

觉得我讲的好可以在评论区夸我

#include 
using namespace std;
#define int long long
const int maxn=2e5+10;
int n,t,dp[maxn][3],flag,h[maxn],p[maxn],m;
vectorvec[maxn];
void dfs(int u,int fa)
{
	if( vec[u].size()==1&&u!=1 )//到达叶子节点 
	{
		if( p[u]> t;
	while( t-- )
	{
		flag=1;
		cin >> n >> m ;
		for(int i=1;i<=n;i++)	scanf("%lld",&p[i]);
		for(int i=1;i<=n;i++)	scanf("%lld",&h[i]);
		for(int i=1;i

一起加油努力啊~

你可能感兴趣的:(div题解)