首先是 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。

最新文章

  1. Swift编程语言简介
  2. Windows Git+TortoiseGit简易使用教程
  3. poj 2187 凸包加旋转卡壳算法
  4. JUnit3 结合一个除法的单元测试说明Assert.fail()的用法
  5. icon-font自己探索得到的经验
  6. 简单的面向对象(OO)练习
  7. InheritableThreadLocal类原理简介使用 父子线程传递数据详解 多线程中篇(十八)
  8. osg做的路面项目
  9. windows查看端口占用 windows端口占用 查找端口占用程序 强制结束端口占用 查看某个端口被占用的解决方法 如何查看Windows下端口占用情况
  10. vetur插件提示 'v-for' directives require 'v-bind:key' directives.错误的解决办法
  11. 《闲聊 ASP.NET Core》系列直播清单
  12. [Linux]systemd和sysV
  13. C# 类&结构体&枚举
  14. Reveal:分析iOS UI的利器
  15. C# winform窗体间传值(使用委托或事件)
  16. java去除数组中重复的元素方法总结
  17. 组合数学 - BZOJ 3997 - TJOI2015
  18. 洛谷P1919 A*B problem 快速傅里叶变换模板 [FFT]
  19. 让指定JS出现智能提示
  20. Java线程面试题:子线程先运行 2 次,然后主线程运行 4 次,如此反复运行 3 次

热门文章

  1. 【PHP设计模式 07_ZeRenLian.php】责任链模式
  2. 工作上的C/C++相关
  3. nodepad + 插件
  4. ACM题目————反约瑟夫问题
  5. 深入学习netty系列(1)
  6. PHP中cookie和Session
  7. C# 添加.DLL 出错的解决方法
  8. Poj(3522),UVa(1395),枚举生成树
  9. userdebug版本开机串口log打开
  10. Log4net使用指南