做点简单 DP 陶冶情操。
考虑按以下方式行动必然不劣:
对于路径上每个点,以其为根,首先穿到不在路径上的点的子树中移动(并且这些边最多往返各经过一次),然后回到路径上走到下一个点。
考虑求出每个点为根时在各个子树内移动的最小代价,查询时减掉路径上的相邻点的贡献即可。
记其为 fu。
不妨先计算 gu 为任选一根时不考虑 u 的当前根向子树的答案。那么有显然转移 gu=au+∑v∈child(u)max{0,gv−z(u,v)−z(v,u)}
对于 u 和 v∈child(u),考虑按换根套路计算 fv,无非是 gv+max{0,fu−max{0,gv−z(u,v)−z(v,u)}−z(u,v)−z(v,u)}。
对于询问 (x,y),先计算路径上的边权和,然后剩下的部分就是 flca(x,y)+∑u∈path(x,y)∖{lca(x,y)}(gu−max{0,gu−z(u,fa(u))−z(fa(u),u)})=flca(x,y)+∑u∈path(x,y)∖{lca(x,y)}min{gu,z(u,fa(u))+z(fa(u),u)}
代码:
1 |
|