洛谷 P3959

NOIP 2017 提高组

给定 \(n\) 个点,\(m\) 条边的无向连通图。要选出一棵有根生成树,设 \(u\)\(fa_u\) 之间的边长度为 \(l_u\),总代价为 \(\sum l_u \cdot dis(u, root)\),求最小总代价是多少?

\(n \le 12, m \le 1000\)

看看数据范围要能想到是状压。大概率不是 \(2^n\)

首先还是要先把 \(root\) 确定好,不然不好做。令 \(f(S)\) 表示 \(S\) 中的点组成的生成树的最小代价,然后发现不好转移,因为你无法确定加入的点的最小深度。

这有个小 trick,我们可以一层层的加入节点,这样加入节点 \(u\) 时只跟上一层又哪些节点有关了。于是可以设计出这样一个状态:令 \(f(d, S, T)\) 表示现在生成树已经有了 \(d\) 层,\(S\) 内的点在生成树中,最后一层组成的节点是 \(T\),枚举第 \(d + 1\) 层的点 \(T'\),就有了个 \(O(n^24^n)\) 的做法。

考虑优化,其实发现 \(T\) 其实是可以抛弃的(似乎也只有这个可能抛弃)。我们之所以要记录这一维,是因为我们要知道哪些点可能在第 \(d + 1\) 层,实际上直接将 \(T\) 看成 \(S\) 是无所谓的,因为不与 \(T\) 相连但与 \(S - T\) 相连的点显然放在更低层更优(\(d\) 更小但 \(l\) 不变),枚举到也无所谓。

于是时间复杂度变成了 \(O(n^23^n)\),需要枚举子集。

运用了一个按层加入的 trick,设计出一个比较又前途的 DP,再优化掉一维即可。

posted @ 2025-12-08 20:55  xiehanrui0817  阅读(0)  评论(0)    收藏  举报