[bzoj2286][Sdoi2011]消耗战(虚树上的DP)
2015-03-30 23:11
239 查看
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2286
分析:对于普通的树形dp:f[x]=min(∑f[son],m[x]),其中f[x]表示以x为根的子树所有关键点全部断开所需要的最少代价,m[x]表示从根节点到x节点的路径上最短的边
这样的话复杂度是n*m的,明显TLE
注意到数据范围里提到,所有询问的总的点数<=n,也就是说询问虽然很多,但每次询问的点的个数不多,也就是说如果对所有的点做树形dp就很不值得
于是我们就要取出那些有用的点来构造成新的树,这个树的节点个数很少,可以很快的算出结果,这个树称为虚树
很容易知道虚树要包含所有的关键点、根节点、关键点之间的lca
下面说下虚树的构造方法:
我们要维护个单调栈,使得每时每刻栈中的点都是深度单增的一条链上的点
按照关键点的dfs序依次入栈,当x入栈时候,从次栈顶向栈顶连边,并弹出栈顶,直到当前栈顶和x的lca的深度比当前次栈顶的深度大,那么就应该把当前栈顶和lca连边并弹出栈顶,然后再将lca入栈(注意判断如果栈顶已经是lca,即lca是关键点,那么就不要再次入栈了),再将x入栈。
分析:对于普通的树形dp:f[x]=min(∑f[son],m[x]),其中f[x]表示以x为根的子树所有关键点全部断开所需要的最少代价,m[x]表示从根节点到x节点的路径上最短的边
这样的话复杂度是n*m的,明显TLE
注意到数据范围里提到,所有询问的总的点数<=n,也就是说询问虽然很多,但每次询问的点的个数不多,也就是说如果对所有的点做树形dp就很不值得
于是我们就要取出那些有用的点来构造成新的树,这个树的节点个数很少,可以很快的算出结果,这个树称为虚树
很容易知道虚树要包含所有的关键点、根节点、关键点之间的lca
下面说下虚树的构造方法:
我们要维护个单调栈,使得每时每刻栈中的点都是深度单增的一条链上的点
按照关键点的dfs序依次入栈,当x入栈时候,从次栈顶向栈顶连边,并弹出栈顶,直到当前栈顶和x的lca的深度比当前次栈顶的深度大,那么就应该把当前栈顶和lca连边并弹出栈顶,然后再将lca入栈(注意判断如果栈顶已经是lca,即lca是关键点,那么就不要再次入栈了),再将x入栈。
相关文章推荐
- bzoj 2286 [Sdoi2011]消耗战(虚树+树上DP)
- [SDOI2011][bzoj2286] 消耗战 [虚树+dp]
- [SDOI2011][BZOJ2286] 消耗战|虚树|树型dp|树上倍增LCA
- 【BZOJ2286】消耗战(SDOI2011)-虚树+树形DP
- BZOJ2286 [Sdoi2011]消耗战 (虚树 + 树形DP)
- 【虚树+树形DP】BZOJ2286(Sdoi2011)[消耗战]题解
- [BZOJ2286][Sdoi2011]消耗战(虚树+lca+树形dp)
- 【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP
- 【 bzoj 2286 】 : [Sdoi2011]消耗战 - 树形DP
- [BZOJ2286][SDOI2011]消耗战(虚树+树形DP)
- BZOJ 2286 [Sdoi2011]消耗战(虚树+树形DP)
- 【BZOJ 2286】[Sdoi2011消耗战 虚树+dp
- 【BZOJ2286】【SDOI2011】消耗战 [虚树][树形DP]
- 【BZOJ】2286: [Sdoi2011消耗战【虚树DP】
- BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】
- BZOJ 2286: [Sdoi2011]消耗战 虚树 树形dp
- 【bzoj2286】[Sdoi2011消耗战 虚树+dp
- BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】
- [BZOJ2286][SDOI2011]消耗战(虚树DP)
- bzoj 2286: [Sdoi2011消耗战 (虚树+树形DP)