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.[HNOI2004]树的计数
题意:给定一棵树中每个节点的度数(d_i),求满足条件的树的个数,答案不超过(1e17)
做法:由上面的性质可知,每个点会在(prufer)序列中出现(d_i-1)次,求树的个数等价于求序列个数,那么这就变成了一个多重集排列问题,套用公式可得:
(ans = frac{(n-2)!}{prod_{i=1}^n(d_i-1)!})
另外此题需要一些特判,如(Sigma(d_i-1)
eq n-2),或者只有一个点,又或者(d_i=0),这里不再赘述(虽然已经说完了)
由于计算过程中可能炸(longlong),需要高精度除法或者分解质因数化除为减
2.[HNOI2008]明明的烦恼
题意:同上,如果给定的(d_i=-1),则表示这个点的度数不受限制
做法:设(cnt)表示(d_i eq-1)的点的个数,(sum)表示(Sigma(d_i-1))(前提是(d_i eq-1)),于是这些点和上题一样满足(假设(d_{1-cnt})是( eq -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})
用第一题的做法做即可,乘法加法要用高精度