关于树上拓扑序计数

树上拓扑序计数

概念:

树上拓扑序指的是满足所有父节点都比儿子节点先出现的排列的个数。

基础推导:

我们最开始可以设出一个 \(dp_u\) 表示以 \(u\) 为根的子树的拓扑序个数。我们考虑怎么向父亲进行合并,此时相当于给前若干个儿子和当前儿子的拓扑序进行合并。两个有序序列的合并可以简单组合数算出。设前面的序列有 \(X\) 个元素,后面有 \(Y\) 个元素,此时相当于在 \(X+1\) 个空中放入 \(Y\) 个元素,插板可得为 \(C_{X+Y}^{Y}\)。令第 \(j\) 个儿子为 \(son_j\),设当前为第 \(k\) 个儿子,那么方案为 \(dp_v \times C_{\sum _{j=1}^{j=k} sz_{son_j}}^{sz_v}\)。把 \(C\) 拆开乘起来就是 \({dp_{now}}=(sz_{now}-1)! \prod \frac{dp_v}{sz_v!}\)。把 \((sz_{now}-1)!\) 变为 \(\frac{sz_{now}!}{sz_{now}}\) ,通过 \(dp\) 迭代与抵消容易得到式子实际上就是 \(\frac{n!}{\prod sz_u}\)。

例题:

P15578 [USACO26FEB] Random Tree Generation G

简要题意:给定一棵树,建树方法是对于 \(i=2 \sim n\) 向 \(randint(1,i-1)\) 连边,然后再随机一个排列对应原序列的每一个位置,求生成原树的概率。

思路 :概率等于算方案。首先发现原题中的建树方式实际上是钦定 \(1\) 为根再进行顺次建树,但进行排列之后打乱了原序列的根,于是考虑枚举根,发现连边方案其实是按树的拓扑序进行连边的,于是枚举根之后跑树上拓扑序计数即可。

P10013 [集训队互测 2023] Tree Topological Order Counting

简要题面:给定一棵有根树,定义排名为树上拓扑序的位置,给每个排名一个权值,对于每个点求出排名方案乘上权值的和。

思路:暴力的想,我们想求出每个点每个排名的方案数是多少,首先子树中的点不影响当前这个点的排名,于是可以把子树内和子树外分开算最后再进行合并。我们可以设 \(dp_{u,rk}\) 表示只考虑子树外的点 \(u\) 的排名为 \(rk\) 的方案。我们现在考虑怎么从 \(dp_{u,i}\) 转移到 \(dp_{v,j}\),首先我们已经确定了排名小于等于 \(rk\) 的点,那 \(u\) 子树外就还有 \(n-sz_u-(rk-1)\) 个点,然后我们考虑合并 \(u\) 的其他儿子,数量为 \(sz_{u}-sz_{v}-1\),由于他们排名都一定在 \(rk\) 之后,我们把他们的相对顺序进行合并,然后我们还需要保证的是 \(u\) 和其他儿子有树上拓扑序的顺序。之后我们只需要把 \(v\) 插在这些点中间,达到他的排名即可。

posted @ 2026-03-05 22:04  lmy333  阅读(29)  评论(0)    收藏  举报