[Notes] Prüfer 序列
概论
本质:完全图生成树与数列之间的双射。
主要用途:
- 将有标号无根树的组合计数问题转换为序列的计数问题。
- 生成树高期望为 \(O(\sqrt{n})\) 的随机树。
构建与还原
过程
构建:每次选择编号最小的叶子结点删除,并将其相连结点加入 Prüfer 序列。
还原:通过 Prüfer 序列维护当前叶子结点集合,从前往后将编号最小的叶子结点与 Prüfer 序列中结点相连,并更新叶子集合。
显然需要编号最小的叶子可以通过堆优化实现,但由于每次处理一个叶子时至多只会引入一个新的叶子结点,因此可以指针扫描线性处理(类似带删除求 \(\text{mex}\))。
实现
代码为方便实现,将 \(n\) 号结点视为根节点,由此得出父亲数组。
int n, opt;
int p[N], fa[N], d[N];
void encode() { // 已知树形态,编码求出 Prüfer 序列
for (int i = 1; i < n; i++) ++d[fa[i]], ++d[i];
int ptr = -1;
for (int i = 1; i <= n; i++) {
if (d[i] == 1 && ptr == -1) ptr = i;
}
int leaf = ptr;
for (int i = 1; i <= n-2; i++) {
int now = fa[leaf];
p[i] = now;
if (--d[now] == 1 && now < ptr) {
leaf = now;
} else {
++ptr;
while (d[ptr] != 1) ++ptr;
leaf = ptr;
}
}
}
void decode() { // 已知 Prüfer 序列,解码求出树形态
for (int i = 1; i <= n; i++) d[i] = 1;
for (int i = 1; i <= n-2; i++) ++d[p[i]];
int ptr = 1;
while (d[ptr] != 1) ++ptr;
int leaf = ptr;
for (int i = 1; i <= n-2; i++) {
fa[leaf] = p[i];
if (--d[p[i]] == 1 && p[i] < ptr) {
leaf = p[i];
} else {
++ptr;
while (d[ptr] != 1) ++ptr;
leaf = ptr;
}
}
fa[leaf] = n;
}
* 组合计数结论
Cayley 定理
Cayley 定理:一个有标号完全图存在 \(n^{n-2}\) 棵生成树。
推论 1(广义 Cayley 定理):\(n\) 个点形成有 \(k\) 棵树的有标号无根树森林,使得给定的 \(k\) 个点两两不属于同一棵树,此时的方案总数为 \(k\cdot n^{n-k-1}\)。
- 证明一(数学归纳法): 结论在 \(n=1\) 时显然成立,当 \(n\geq 1\) 时,若对于 \(n-1\) 有 \(\forall 1\leq k\leq n-1,F(n-1,k)=k(n-1)^{n-k-1}\) 成立,尝试证明结论对 \(n\) 成立。
设定理描述的方案数为 \(F(n,k)\)(\(1\leq k\leq n\)),令被钦定的 \(k\) 个点标号为 \([n-k+1, n]\),枚举度数 \(d\) 得到递推式为:\[F(n,k)=\sum_{d=0}^{n-k}\binom{n-k}{d}F(n-1, k+d-1) \]因此有:\[\begin{align*} F(n,k)&=\sum_{d=0}^{n-k}\binom{n-k}{d}(k+d-1)(n-1)^{n-k-d-1}\\ &=\frac{1}{n-1}\sum_{d=0}^{n-k}\binom{n-d}{d}(k-1)(n-1)^{n-k-d}+\frac{1}{n-1}\sum_{d=0}^{n-k}\binom{n-k}{d}d(n-1)^{n-k-d}\\ &=\frac{k-1}{n-1}\sum_{d=0}^{n-k}\binom{n-k}{d}(n-1)^{n-k-d}+\frac{n-k}{n-1}\sum_{d=0}^{n-k}\binom{n-k-1}{d-1}(n-1)^{n-k-d}\\ &= \frac{k-1}{n-1}\cdot n^{n-k}+\frac{n-k}{n-1}\cdot n^{n-k-1}\\ &=s\cdot n^{n-k-1} \end{align*} \] - 证明二(组合意义):添加虚点 \(0\) 并将钦定的 \(k\) 个点均接到 \(0\) 上,问题转换为指定点度数为 \(k\) 的 \(n+1\) 点生成树计数。
通过除法原理,可以转换为任意 \(k\) 个点接到 \(0\) 上的方案数除以 \(\binom{n}{k}\)。
因此方案数为:\[\frac{\binom{n-1}{k-1}n^{n-k-1}}{\binom{n}{k}}=k\cdot n^{n-k-1} \]
推论 2:指定点度数的生成树方案数为 \(\dfrac{(n-2)!}{\prod_{i=1}^{n}(d_i-1)!}\)。
有标号连通块计数
定理:若 \(n\) 个点已被连成大小为 \(\{s_i\}_{i=1}^{k}\) 的 \(k\) 个连通块,则在这些连通块之间加边构成生成树的方案数为 \(n^{k-2}\prod_{i=1}^{k}s_i\)。
证明:在连通块之间连边时,可以将这 \(k\) 个连通块视作点,枚举每个连通块 \(i\) 向外连出的边数量 \(d_i\),则连边的总方案数为:
\[\begin{align*}
&\sum_{\{d_i\}_{i=1}^{k}\mid \sum_{i=1}^{k}d_i=2(k-1)\vee\forall i,d_i\geq 1}\binom{k-2}{d_1-1,d_2-1,\dots,d_k-1}\prod_{i=1}^{k}s_i^{d_i}\\
&=(\sum_{\{d_i\}_{i=1}^{k}\mid \sum_{i=1}^{k}d_i=2(k-1)\vee\forall i,d_i\geq 1}\binom{k-2}{d_1-1,d_2-1,\dots,d_k-1}\prod_{i=1}^{k=1}s_i^{d_i-1})\cdot\prod_{i=1}^{k}s_i
\end{align*}
\]
发现括号中的式子为多元二项式展开多项式展开,因此可以进一步转化:
\[\begin{align*}
(\sum_{\{d_i\}_{i=1}^{k}\mid \sum_{i=1}^{k}d_i=2(k-1)\vee\forall i,d_i\geq 1}\binom{k-2}{d_1-1,d_2-1,\dots,d_k-1}\prod_{i=1}^{k=1}s_i^{d_i-1})\cdot\prod_{i=1}^{k}s_i&=(\sum_{i=1}^{k}s_i)^{k-1}\cdot\prod_{i=1}^{k}s_i\\
&=n^{k-2}\prod_{i=1}^{k}s_i
\end{align*}
\]
该结论使用 \(\text{Matrix Tree}\) 定理亦可证明,不展开赘述。

浙公网安备 33010602011771号