CF1120D Power Tree(树形DP/构造+差分+最小生成树)

解法一:树形DP

个人觉得这个方法是比较可能想到的,但是输出方案很恶心

先转换题意:“无论怎样规定叶子的初始点权,都可以通过操作你选择的点来让所有叶子的点权清空”意味着每个叶子节点都可以通过一系列操作单独+1、-1

模拟一下就可以发现,以u为根的子树中,

要想通过控制 u u u u u u的祖先(不管是 u u u 还是 u u u的祖先 都同时覆盖了子树内的所有叶子节点)
使子树内所有叶子节点均可以单独+1、-1,

至多一个叶子节点未被覆盖,

且被覆盖的叶子节点一定要可以单独+1、-1

那么状态定义就很显然了:

f [ u ] [ 0 ] f[u][0] f[u][0] 表示以 u u u 为根的子树内叶结点全部被覆盖,

f [ u ] [ 1 ] f[u][1] f[u][1] 表示以 u u u 为根的子树内叶结点剩一个未覆盖

状态转移方程为:

u u u 非叶子节点:

f [ u ] [ 1 ] = ∑ f [ v i ] [ 0 ] − m a x { f [ v i ] [ 0 ] − f [ v i ] [ 1 ] } f[u][1]=\sum f[v_i][0]-max\{ f[v_i][0]-f[v_i][1]\} f[u][1]=f[vi][0]max{ f[vi][0]f[vi][1]}

f [ u ] [ 0 ] = m i n { ∑ f [ v i ] [ 0 ] , f [ u ] [ 1 ] + c [ u ] } f[u][0]=min\{\sum f[v_i][0],f[u][1]+c[u]\} f[u][0]=min{ f[vi][0],f[u][1]+c[u]}

u u u 为叶子节点:

f [ u ] [ 1 ] = 0 f[u][1]=0 f[u][1]=0

f [ u ] [ 0 ] = c [ u ] f[u][0]=c[u] f[u][0]=c[u]

至于如何输出方案,可以看一下这里


解法二:构造 + 差分 + 最小生成树

博客

补充一下自己的理解:

区间加操作, l u l_u lu 加一个数, r u + 1 r_u+1 ru+1 减一个数,最后每个数的实际值是前面各数(包括自己)的和

题目要求第1至k个数的前缀和均为0,

则第1至k个数均为0,只有第k+1个数最后不为0(即前面的数通过操作把值全部转移到第k+1个数去)

操作就是我们连的边

那么就只有选择的边构成连通图才能办到

猜你喜欢

转载自blog.csdn.net/Emma2oo6/article/details/114414627