prufer序列是什么?
百度百科这样说:
Prufer数列是无根树的一种数列。在组合数学中,Prufer数列由有一个对于顶点标过号的树转化来的数列,点数为n的树转化来的Prufer数列长度为n-2。它可以通过简单的迭代方法计算出来。
与无根树的转换
1.无根树转prufer序列
重复以下步骤直至只剩下两个点:
找到度数为1的且编号最小的节点x,将它所连接的节点加入\(prufer\)序列一次,然后删掉x
2.prufer序列转无根树
准备好一个点集(\({1,2,3,4,....,n}\))
重复以下步骤直至\(prufer\)序列为空:
找到点集中还存在的且在当前的prufer序列中未出现的最小的一个点v,用当前\(prufer\)序列的第一个数\(u\),将\(u\)和\(v\)连边,然后删除\(u\)和\(v\)
性质
该序列长度为\(n-2\)(废话)
一个度数为\(d_i\)的点会在序列中出现\(d_i-1\)次(它的度从\(d_i\)变成1共加入序列了\(d_i-1\)次)
\(prufer\)序列与无根树一一对应,这意味着求无根树的个数等价于求\(prufer\)序列的个数,活生生的将树上问题(误)转换为了序列问题
题目
1.
题意:给定一棵树中每个节点的度数\(d_i\),求满足条件的树的个数,答案不超过\(1e17\)
做法:由上面的性质可知,每个点会在\(prufer\)序列中出现\(d_i-1\)次,求树的个数等价于求序列个数,那么这就变成了一个多重集排列问题,套用公式可得:
\(ans = \frac{(n-2)!}{\prod_{i=1}^n(d_i-1)!}\)
另外此题需要一些特判,如\(\Sigma(d_i-1)\neq n-2\),或者只有一个点,又或者\(d_i=0\),这里不再赘述(虽然已经说完了)
由于计算过程中可能炸\(longlong\),需要高精度除法或者分解质因数化除为减
2.
题意:同上,如果给定的\(d_i=-1\),则表示这个点的度数不受限制
做法:设\(cnt\)表示\(d_i\neq-1\)的点的个数,\(sum\)表示\(\Sigma(d_i-1)\)(前提是\(d_i\neq-1\)),于是这些点和上题一样满足(假设\(d_{1-cnt}\)是\(\neq -1\)的点):
\(p = \frac{sum!}{\prod_{i=1}^{cnt}(d_i-1)!}\)
由于总共有\(n-2\)个位置,这\(sum\)个位置的选法有\(C_{n-2}^{sum}\)种
剩下的\((n-cnt)\)个点可以在剩下的\((n-2-sum)\)个位置出现任意次数,即有\((n-cnt)^{n-sum-2}\)种选择
所以有:
\(ans=C_{n-2}^{sum}*p*(n-cnt)^{n-sum-2}\)
化简可得:
\(ans=\frac{(n-2)!}{(n-2-sum)!\prod(di-1)!}*(n-cnt)^{n-sum-2}\)
用第一题的做法做即可,乘法加法要用高精度