#P16406. Tree Similarity
Tree Similarity
题目背景
在树形文档、语法树和目录结构的版本比较中,我们经常需要衡量两棵树之间究竟相差多少。对于普通字符串,可以使用编辑距离;而对于有根有序树,删除或插入一个节点还会改变其子节点的归属,因此情况更加复杂。
现在给定两棵带标签的有根有序树,请计算把第一棵树变成第二棵树所需的最少操作次数。
题目描述
给定两棵带标签的有根有序树 和 。
你可以对树 执行以下三种操作:
- 修改一个节点的标签;
- 删除一个非根节点;
- 在根节点下方的某个位置插入一个新节点。
每次操作的代价均为 。
有序树
若一个节点有 个儿子,则这些儿子按照从 到 的顺序排列。也就是说,它们之间存在“第一个儿子”“第二个儿子”等明确的先后关系。
两棵树等价,当且仅当:
- 两棵树的根节点标签相同;
- 两个根节点的儿子数量相同;
- 对每个 ,第一棵树根节点的第 棵儿子子树与第二棵树根节点的第 棵儿子子树等价。
删除节点
设非根节点 是节点 的第 个儿子,并且 按顺序有 个儿子。
删除 后:
- 的第一个儿子成为 的第 个儿子;
- 的第二个儿子成为 的第 个儿子;
- 依此类推;
- 原来位于 后面的儿子整体向后移动;
- 所有儿子的相对顺序保持不变。
也就是说,删除一个节点后,它的儿子会按照原顺序直接接到它的父亲下面。
插入节点
插入操作是删除操作的逆过程。
你可以选择任意节点 作为新节点 的父亲,并选择 的儿子序列中的一个连续子段,让这个连续子段中的所有节点按照原顺序成为 的儿子,再用 取代这个连续子段在 的儿子序列中的位置。
所选连续子段可以为空。此时, 不带儿子,可以插入到 的儿子序列中的任意位置。
新插入节点的标签可以任意指定。
根节点不能被删除,也不能在原根节点上方插入新的父节点,但可以修改根节点的标签。
请计算把 变成与 等价的树所需的最少操作次数。
输入格式
第一行包含两个整数 ,分别表示树 和树 的节点数。
接下来 行描述树 。节点编号为 。
第 行描述编号为 的节点,格式为:
label c child_1 child_2 ... child_c
其中:
label表示该节点的标签;- 表示该节点的儿子数量;
- 后面的 个整数按照从左到右的顺序给出其儿子编号。
接下来 行以相同格式描述树 ,其节点编号为 。
每棵树的根节点是唯一一个没有作为其他节点儿子出现的节点。
输出格式
输出一个整数,表示把 变成与 等价的树所需的最少操作次数。
样例输入
3 2
6 0
1 2 0 2
4 0
2 1 1
4 0
样例输出
2
样例说明
第一棵树的根节点是节点 ,其两个儿子的标签依次为 和 。
可以先删除标签为 的叶子节点,再把根节点的标签从 修改为 ,共需 次操作。
数据范围
对于全部数据:
- ;
- 节点标签是能够存入 32 位有符号整数的非负整数,即 ;
- 输入保证每一部分都构成一棵合法的有根有序树。