题意:给你由N个点构成一颗树,问要孤立出一个有P个节点的子树最少需要删除多少条边。N的范围最大为150
N的范围不大,很容易想到在树上面做背包。把每个节点都看成一个背包,然后把每个儿子节点都看成是一组物品。为什么是一组呢,那是因为假设以儿子为根的节点的子树有S个节点,那么就有S+1种情况,要么将这整棵子树舍弃,要么从这个子树中取1-S个节点。
设f[i][j]为以i为根节点的子树,孤立出以i为根节点,一共含有j个节点的子树最少需要删除的边数(不包括删除i和他父亲的连接的那条边(假设i不是根节点))。
从根节点开始dfs,对于每个节点做一次分组背包,如果不要这颗子树的话分组讨论
不要这个子树f[i][j]:f[i][j] = f[i][j]+1
取这个子树当中的节点 f[i][j] = min(f[i][j-k],f[i.child[a]][k])
所以总的就是f[i][j] = min(f[i][j]+1,min(f[i][j-k],f[i.child[a]][k])
注意最后那颗子树可能不是以原来的root为根的
#include #include #include #include #include #include #include