Prüfer 序列学习笔记
0. 前言
Prüfer 序列,在 NOI 大纲中属于 9 级,是一个比较冷门(?)的算法。Prüfer 序列的实现与理解是十分简单与易懂的,这篇文章会将笔者学习 Prüfer 序列 的经历简要概述,非常适合初学者进行阅读。
1.Prüfer 序列概念引进
1.1 举例
我们引进一颗较为简单的树,如下图:
我们进行下列操作:
- 找到当前树中叶子节点中编号最小的,记为
u_i 。 - 选定与
u_i 相连接的节点,记为v_i 。 - 将
v_i 加入一个用于记录的序列,然后删除节点u_i 和u_i - v_i 的连边,重复上述操作直到原图仅剩两个节点。
例如上图中给定的例子最终得到的序列为
我们可以发现,由于一棵树每一次被选定的节点是固定的,所以对于每一棵不同的树都对应着一个上述中的序列,我们称这个序列为Prüfer 序列。
可证明一个 Prüfer 序列是对应唯一一棵树且可以与其相互转化的。
1.2 证明
1.2.1 树对应的序列的唯一性
这个很好证明,因为对于一棵树经历过若干次操作后的状态,接下来操作的节点是可确定的。
1.2.2 序列转换成树
我们还是拿上图举例。
已知有一颗有标号的顶点的树,节点数量为
注意到在一棵树的 Prüfer 序列中未出现的节点一定为这棵树的叶子结点。
我们将所有叶子结点首先加入一个最小堆,容易发现第一次操作选中的是 Prüfer 序列的第一项与编号最小的一个叶子节点的连边,于是我们将此连边选中。
例如在序列
由于
容易发现递归边界为 Prüfer 序列中仅存在一个节点
我们可以把上面归成下面几个步骤:
- 将原 Prüfer 序列中未存在的点加入维护叶子结点编号最小值的堆,并记录所有节点在原 Prüfer 序列中出现的次数;
- 选中当前 Prüfer 序列第一个节点,将该节点与当前最小的叶子结点进行连边;
- 将选中的最小叶子结点从堆中删除,当前第一个节点减去
1 ,如果该节点次数减至0 ,将其加入叶子结点的堆。 - 删去当前 Prüfer 序列第一个节点,并重新维护叶子结点最小值。回到第二步继续执行操作直到无法操作。
至此,我们完成了由 Prüfer 序列向树的转换,接下来要证明 Prüfer 序列对应的树的唯一性。
1.2.3 序列对应树的唯一性
发现我们在 1.2.2 中将序列转换成树的操作每一步都是唯一的,所以一个 Prüfer 序列对应的树的每一条边都是唯一的,自然这棵树是唯一的。
由这个结论我们可以很轻松地证明 Cayley 定理。
Cayley 定理 :
n 个有标号的顶点的树的数目为n^{n-2} 。
我们可以发现,
可以发现 Prüfer 序列的
2. Prüfer 序列相关例题
Prüfer 序列模板题:P6086 【模板】Prufer 序列
Cayley 定理模板题:UVA10843 Anne's game
3. 后言
这里本应该有一些长篇大论的东西,但笔者觉得没必要写就咕了。
欢迎补充和指出问题awa