1 条题解
-
0
F. Tree Factory 详细题解
问题理解
我们有一棵目标树,根为 ,满足父节点编号小于子节点编号。初始状态是一条链(竹竿),每个节点恰好有一个子节点。允许的操作是:选择非根节点 ,且其父节点也不是根,将 的父节点改为其祖父节点。目标是用最少操作次数将链变成目标树,并输出操作序列。
操作的本质
在链中,节点的深度等于它在链中的位置(根深度为 )。操作将节点 向上移动一层,即深度减少 ,其他节点深度不变。因此,每次操作只能将某个节点的深度减少 。
最少操作数的确定
设目标树中节点 的深度为 。初始链中,我们可以任意排列节点的标号,决定每个节点的初始深度。由于链有 个节点,深度集合固定为 ,只是分配给不同节点。
设初始深度为 ,则必须满足 ,因为操作只能减少深度。需要进行的操作次数为 。
总操作次数: $k = \sum_{v=0}^{n-1} (d_{\text{init}}(v) - d_{\text{target}}(v)) = \sum d_{\text{init}}(v) - \sum d_{\text{target}}(v)$
由于 $\sum d_{\text{init}}(v) = 0 + 1 + \cdots + (n-1) = \frac{n(n-1)}{2}$ 固定,因此: $k = \frac{n(n-1)}{2} - \sum_{v=0}^{n-1} d_{\text{target}}(v)$
这个值与初始链的标号分配无关,是最少操作数的下界。我们可以通过合适的分配达到这个下界。
最优初始链的构造
为了达到下界,需要让每个节点的初始深度尽量接近其目标深度,即让深度大的节点分配较大的初始深度。
构造方法:
- 计算目标树中每个节点的深度
- 将非根节点按深度降序排序
- 根节点 放在链的第一个位置(深度 )
- 按排序顺序依次将节点放入链的后续位置
这样能保证每个节点 的初始深度 目标深度,且总差值最小,达到下界。
操作序列的生成
得到初始链后,需要将每个节点从初始深度降到目标深度。由于操作独立,可以按以下策略生成序列:
- 维护一个优先队列(最大堆),存放当前深度大于目标深度的节点,按当前深度降序排列
- 每次取出当前深度最大的节点
- 执行操作:将 的父节点改为祖父节点(即向上移动一层)
- 更新 的深度(减少 )
- 如果深度仍大于目标深度,重新加入队列
这样能保证操作过程合法,且最终达到目标树。
正确性证明
引理1:最少操作数为
证明:每次操作只能减少某个节点的深度 ,初始深度总和固定,目标深度总和固定,因此至少需要差值次操作。构造的初始链使每个节点的初始深度 目标深度,且总差值恰好等于该值,因此达到下界。
引理2:按深度降序分配初始深度保证
证明:设节点按深度降序排列为 ,则 $depth[v_1] \ge depth[v_2] \ge \cdots \ge depth[v_{n-1}]$。分配初始深度时, 得到深度 , 得到深度 ,…, 得到深度 。对于任意节点 ,假设它在排序中位置为 ,则 。由于至少有 个节点深度 (包括 本身),所以 ?实际上根节点占用了深度 ,所以非根节点的初始深度至少为 ,且 。
引理3:操作序列有效且能达到目标树
证明:操作过程中始终保持树结构合法(不会产生环),因为每次只改变一个节点的父节点为其祖先,不会破坏树性质。每个节点独立地从初始深度下降到目标深度,最终所有节点深度正确,且父子关系正确(因为深度差为 的节点父子关系唯一确定)。
时间复杂度
- 计算深度:
- 排序:
- 优先队列操作:,其中 是操作次数
- 总复杂度:,满足 , 的要求
关键观察
- 操作独立:每次操作只影响一个节点的深度,不改变其他节点的相对位置关系
- 深度和守恒:初始深度和固定,目标深度和固定,操作次数由两者差值决定
- 贪心分配:深度大的节点应获得较大的初始深度,这是达到下界的必要条件
- 模拟可行性:优先队列保证每次处理深度最大的节点,避免冲突
这个解法巧妙地利用了操作的性质,将复杂的树变换问题转化为深度分配和模拟问题,体现了算法设计中的转化思想。
- 1
信息
- ID
- 6202
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者