首先是 Martrix67 的博文:http://www.matrix67.com/blog/archives/682
然后是morejarphone同學的博文:http://blog.csdn.net/morejarphone/article/details/50677172
因為是偶然翻了他的這篇博文,然后就秒會了。
prufer數列,可以用來解一些關於無根樹計數的問題。
prufer數列是一種無根樹的編碼表示,對於一棵n個節點帶編號的無根樹,對應唯一一串長度為n-1的prufer編碼。
(1)無根樹轉化為prufer序列。
首先定義無根樹中度數為1的節點是葉子節點。
找到編號最小的葉子並刪除,序列中添加與之相連的節點編號,重復執行直到只剩下2個節點。
如下圖的樹對應的prufer序列就是3,5,1,3。
具體實現可以用一個set搞定,維護度數為1的節點。復雜度O(nlogn)。
(2)prufer序列轉化為無根樹。
設點集V={1,2,3,...,n},每次取出prufer序列中最前面的元素u,在V中找到編號最小的沒有在prufer序列中出現的元素v,給u,v連邊然后分別刪除,最后在V中剩下兩個節點,給它們連邊。最終得到的就是無根樹。
具體實現也可以用一個set,維護prufer序列中沒有出現的編號。復雜度O(nlogn)。
最后有一個很重要的性質就是prufer序列中某個編號出現的次數就等於這個編號的節點在無根樹中的度數-1。
一棵n個節點的無根樹唯一地對應了一個長度為n-2的數列,數列中的每個數都在1到n的范圍內。
上面這句話比較重要。通過上面的定理,
1)我們可以直接推出n個點的無向完全圖的生成樹的計數:n^(n-2) 即n個點的有標號無根樹的計數。
2)一個有趣的推廣是,n個節點的度依次為D1, D2, …, Dn的無根樹共有 (n-2)! / [ (D1-1)!(D2-1)!..(Dn-1)! ] 個,因為此時Prüfer編碼中的數字i恰好出現Di-1次。
即 n種元素,共n-2個,其中第i種元素有Di-1個,求排列數。
3)n個節點的度依次為D1, D2, …, Dn,令有m個節點度數未知,求有多少種生成樹?(BZOJ1005 明明的煩惱)
令每個已知度數的節點的度數為di,有n個節點,m個節點未知度數,left=(n-2)-(d1-1)-(d2-1)-...-(dk-1)
已知度數的節點可能的組合方式如下
(n-2)!/(d1-1)!/(d2-1)!/.../(dk-1)!/left!
剩余left個位置由未知度數的節點隨意填補,方案數為m^left
於是最后有
ans=(n-2)!/(d1-1)!/(d2-1)!/.../(dk-1)!/left! * m^left
待填之坑:無標號無根樹、有標號有根樹、無標號有根樹的計數。
參見論文 華中師大一附中 趙爽《樹的計數》、南京師范大學附屬中學 顧昱洲《Graphical Enumeration》
n個點的 有標號有根樹的計數:n^(n-2)*n = n^(n-1)
n個點的 無標號有根樹的計數:

n個點的 無標號無根樹的計數:an為 n個點的 無標號有根樹的計數。

待填之坑:度數有限制時的計數。如烷烴的計數,每個點的度數最大為4。

