JZOJ7月22日提高组T1 三色树

题目

Description

给出一个N个节点的无根树,每条边有非负边权,每个节点有三种颜色:黑,白,灰。
一个合法的无根树满足:树中不含有黑色结点或者含有至多一个白色节点。
现在希望你通过割掉几条树边,使得形成的若干树合法,并最小化割去树边权值的和。

Input

第一行一个正整数N,表示树的节点个数。
第二行N个整数Ai,表示i号节点的颜色,0 表示黑色,1表示白色,2表示灰色。
接下来N-1行每行三个整数Xi Yi Zi,表示一条连接Xi和Yi权为Zi的边。

Output

输出一个整数表示其最小代价。

Sample Input

5
0 1 1 1 0
1 2 5
1 3 3
5 2 5
2 4 16

Sample Output

10
样例解释:
花费10的代价删去边(1, 2)和边(2, 5)。

Data Constraint

20%的数据满足N≤10。
另外30%的数据满足N≤100,000,且保证树是一条链。
100%的数据满足N≤300,000,0≤Zi≤1,000,000,000,Ai∈{0,1,2}。

题解

题意

n n 个节点,颜色为0\1\2
对于一个合法树,要求没有颜色0或最多一个颜色1
求出满足最大合法森林需要删去边的最小代价

分析

由于每个节点只有三种颜色,状态简单,很容易想到用树形DP来做这道题。

上面这句话是CJZ巨佬所述 (但我这种蒟蒻就想不到树形DP)
f [ i ] [ 0 ] f[i][0] 表示以节点 i i 为根的子树中不含黑色节点的最小代价
f [ i ] [ 1 ] f[i][1] 表示以节点 i i 为根的子树中不含白色节点的最小代价
f [ i ] [ 2 ] f[i][2] 表示以节点 i i 为根的子树中只含一个白色节点的最小代价
先行告知: s o n son 表示 i i 的儿子, v v 表示 i i s o n son 连接的那条边的权值, a [ i ] a[i] 表示节点 i i 的颜色, i n f inf 正无穷
f [ i ] [ 0 ] f[i][0] 转移:
f [ i ] [ 0 ] = { ( a [ i ] = 0 ) i n f ( a [ i ] 0 ) s o n m i n { f [ s o n ] [ 0 ] v + m i n { f [ s o n ] [ 1 ] f [ s o n ] [ 2 ] f[i][0]=\begin{cases}(a[i]=0)inf\\(a[i]≠0)∑_{son}min\begin{cases}f[son][0]\\v+min\begin{cases}f[son][1]\\f[son][2]\end{cases}\end{cases} \end{cases}
解释:
当节点 i i 的颜色是黑色时
以节点 i i 为根的子树中不含黑色节点是不存在的
所以 f [ i ] [ 0 ] f[i][0] 设为 i n f inf
当节点 i i 的颜色是白色时
对于每个儿子节点
可以全部白色,或者割掉当前节点和儿子节点之间的边,那么儿子节点选什么都无所谓,求个 m i n min 值就可以了
f [ i ] [ 1 ] f[i][1] 转移(其实跟 f [ i ] [ 0 ] f[i][0] 转移基本一样)
f [ i ] [ 1 ] = { ( a [ i ] = 1 ) i n f ( a [ i ] 1 ) s o n m i n { f [ s o n ] [ 1 ] v + m i n { f [ s o n ] [ 0 ] f [ s o n ] [ 2 ] f[i][1]=\begin{cases}(a[i]=1)inf\\(a[i]≠1)∑_{son}min\begin{cases}f[son][1]\\v+min\begin{cases}f[son][0]\\f[son][2]\end{cases}\end{cases} \end{cases}
至于解释嘛,对照 f [ i ] [ 0 ] f[i][0] 的自己思考
f [ i ] [ 2 ] f[i][2] 转移
f [ i ] [ 2 ] = { ( a [ i ] = 1 ) s o n m i n { f [ s o n ] [ 1 ] v + m i n { f [ s o n ] [ 0 ] f [ s o n ] [ 2 ] ( a [ i ] 1 ) f [ i ] [ 1 ] m a x ( m i n { f [ s o n ] [ 1 ] v + m i n { f [ s o n ] [ 0 ] f [ s o n ] [ 2 ] f [ s o n ] [ 2 ] ) f[i][2]=\begin{cases}(a[i]=1)∑_{son}min\begin{cases}f[son][1]\\v+min\begin{cases}f[son][0]\\f[son][2]\end{cases}\end{cases}\\(a[i]≠1)f[i][1]-max(min\begin{cases}f[son][1]\\v+min\begin{cases}f[son][0]\\f[son][2]\end{cases}\end{cases}-f[son][2]) \end{cases}
不要看错
解释:
当当前节点的颜色是白色时
那么它的儿子不能选白色
f [ i ] [ 1 ] f[i][1] 一样
当当前节点不是白色
那么就可以让某个儿子节点的要求放宽一点
求出放宽要求后减少哪些代价
再用没有白色节点的 f [ i ] [ 1 ] f[i][1] 减去最大减少代价
结合代码理解

扫描二维码关注公众号,回复: 11458456 查看本文章

Code

Code

猜你喜欢

转载自blog.csdn.net/LZX_lzx/article/details/107524040
今日推荐