[Prufer 序列 & 计数 & 图论] CodeForces 156D Clues

发布时间 2023-08-25 21:12:07作者: SF71-H

https://www.luogu.com.cn/problem/CF156D

题意

给定一张 \(n\) 个点 \(m\) 条边的带标号无向图,设有 \(c\) 个连通块,求添加 \(c - 1\) 条边使得形成一棵树的方案数,并对 \(p\) 取模。

\(1 \leq n \leq 10^5, 0 \leq m \leq 10^5, 1 \leq p \leq 10^9\)

题解

因为大小为 \(c\) 的树与长度为 \(c - 2\) 的 Prufer 序列是 双射 关系,所以我们可以对 Prufer 序列进行计数。

我们可以把这 \(c\) 个连通块都看成一个点来计算,设第 \(i\) 个连通块在最后的生成树中的度数为 \(d_i\),根据父亲序列转 Prufer 序列的过程,容易发现最后剩下的一条边一定连接根节点和它的其中一个子节点,所以分两种情况讨论:

  • \(i\) 不是根节点,\(i\) 与其子节点的连边都会被删掉,所以 \(i\) 在 Prufer 序列中出现了 \(d_i - 1\) 次。

  • \(i\) 是根节点,因为最后将剩下一条连接根节点和它的其中一个子节点的边,所以\(i\) 在 Prufer 序列中也出现了 \(d_i - 1\) 次。

然后我们就可以确定 Prufer 序列的数量了,即:

\[\dbinom{c - 2}{d_1 - 1, d_2 - 1, \dots, d_c - 1} \]

然后我们开始确定每一个连通块是哪一个点往外连了边,直接乘法原理即可,方案数:

\[\prod_{i = 1}^{c}siz_i ^ {d_i} \]

其中 \(siz_i\) 表示第 \(i\) 个连通块的大小。

整理一下,若这 \(c\) 个连通块在生成树中对应的度数为 \(d_1, d_2, \dots, d_c\),则方案数为:

\[\dbinom{c - 2}{d_1 - 1, d_2 - 1, \dots, d_c - 1}\prod_{i = 1}^{c}siz_i ^ {d_i} \]

然后我们就要枚举 \(d\) 数组了,先放上来式子:

\[\sum_{d_1 + d_2 + \dots + d_c = 2c - 2}\dbinom{c - 2}{d_1 - 1, d_2 - 1, \dots, d_c - 1}\prod_{i = 1}^{c}siz_i ^ {d_i} \]

很好,这是一个十分丑陋的式子,但是我们有 多项式定理

\[(x_1 + x_2 + \dots + x_n) ^ m = \sum_{t_1 + t_2 + \dots + t_n = m}\dbinom{m}{t_1,t_2,\dots,t_n}\prod_{i = 1}^{n}x_i^{t_i} \]

所以显然,$$\sum_{d_1 + d_2 + \dots + d_c = 2c - 2}\dbinom{c - 2}{d_1 - 1, d_2 - 1, \dots, d_c - 1}\prod_{i = 1}^{c}siz_i ^ {d_i - 1} = (siz_1 + siz_2 + \dots + siz_c) ^ {c - 2} = n^{c - 2}$$

所以答案为 \(\displaystyle n^{c - 2} \times \prod_{i = 1}^{c}siz_i\)

非常好的一道计数题,结合了 Prufer 序列 + 多项式定理。