题目

思路来源
乱搞ac
题解
对于一个u为根的子树,如果出现了这种路径,这个路径要么是(u,v),要么是(v1,v2)
如果是(u,v)的话,得去v子树里刨一个类型相同的点出来
所以,mp[v][x]表示v为子树根,存在一个点p的类型是x,p到v的路径是没用过的最大代价和,用于辅助转移
因为留某个子树不用,肯定是留一个点为了以后用,然后往上启发式合并
合并转移的话,如果用的话是用哪个,再把v往u上挂, 然后考虑u还给不给以后留
而dp[u]表示只考虑u的子树时的最优解,即最大代价和,用于更新答案
更新答案的话,考虑u下有子树v1、v2、v3,
如果v2和v3各存在一条类型是x的路径,就是用dp[v1]+mp[v2][x]+mp[v3][x]更新答案,
用数字表示dp值,用带圈的数字表示mp值,发现
(1+2+③)+(1+②+3)-(1+2+3)=1+②+③,
也就是分成三部分,前两部分是相同结构的,
v3往u上的mp上挂的时候,维护的是v3为子树根,存在一个点p的类型是x,p到v的路径是没用过的最大代价和,也就是③,再加上u下其他子树的dp值之和,也就是1+2,得到1+2+③
而第三部分为u下所有v子树的dp值之和,记为sum
稍稍化简一下,可以得到1+②+③=(1+②+3)-3+③,也就是代码中mp[u][x.fi]+x.se-dp[v]
此外,注意到u的重儿子向u转移的时候,需要全局加上所有轻儿子的dp值之和,
这是一个全局加,所以可以对子树打标记,再魔改下map上维护的值,使之带上子树标记,
于是,now[u]表示对mp[u]上所

最低0.47元/天 解锁文章
643

被折叠的 条评论
为什么被折叠?



