1. 程式人生 > >[生成樹計數]

[生成樹計數]

prufer序列

每個prufer序列對應一棵唯一的樹。

生成:得到一棵樹的prufer序列的方法是依次去掉編號最小的葉子節點(也就是度數為1的點),然後將這個點的父親加入佇列。直到剩下最後兩個點。這樣就可以得到一個長度為n的prufer序列。

根據prufer序列的生成方式可以得到:每個節點會在prufer序列中出現他的度數-1次

還原:找到一個包含編號為1-n這n個節點的集合S,然後每次在S中從小到大找到第一個不在prufer序列中的數,將這個數與序列的第一個節點連一條邊,並且將序列中的節點作為父親。然後將這兩個節點同時從各自所在的序列或集合中刪除,重複上面的操作n-2次。最後集合S中會剩下兩個節點,將這兩個節點連線起來。就可以將prufer序列還原了。

Cayley定理

完全圖的生成樹個數為\(n^{n-2}\)。利用prufer序列考慮,因為每個序列和一棵生成樹是對應的,所以序列的個數其實就是生成樹的個數。prufer序列有n-2個節點,每個節點都有n種選擇。利用乘法原理就可以知道完全圖的不同的prufer序列有\(n^{n-2}\)個。

計數

如果給定n個點並且限制這n個點的度數必須分別是\(d_1,d_2,d_3......d_n\),那麼所能形成的生成樹的個數是\(\frac{(n-2)!}{\prod\limits_{i=1}^n{(d_i-1)!}}\)。這個結論也可以根據prufer證明。因為每個節點在prufer中出現的次數是它的度數減一次。分母上(n-2)!的是全部的排列方式。因為對於節點i有\((d_i-1)!\)
中排列方式是相同的,所以再去除以這些排列方式。

matrix-tree定理

不大會證明,所以直接寫結論和做法吧。

首先要得到一個基爾霍夫矩陣(K)。然後還需要一個度數矩陣(D)和鄰接矩陣(A),具體意義如下

度數矩陣,\(D_{i,i}\)為第i個點的度數,其他位置全部為0

鄰接矩陣,\(A_{i,j}\)=\(A_{j,i}\)=i與j之間的邊數

基爾霍夫矩陣,由D-A得到,就是\(K_{i,j}=D_{i,j}-A_{i,j}\)

上面三個矩陣都是N*N的矩陣,N表示點數

然後去掉K的最後一行和最後一列。然後用高斯消元求出這個新矩陣的上三角矩陣。將上三角矩陣對角線的點相乘所得到的絕對值就是這個圖所能形成的樹的個數。