PruferCode相关

来源:互联网 发布:java详细设计文档模板 编辑:程序博客网 时间:2024/05/22 05:18

树的Prufer 编码和最小生成树计数 (摘自:冰上极光的专栏)
1. 一棵标号树的Pufer编码规则如下:找到标号最小的叶子节点,输出与它相邻的节点到prufer 序列, 将该叶子节点删去,反复操作,直至剩余2个节点。

 

2. 由Pufer编码生成树:任何一个prufer 序列可以唯一对应到一棵有标号的树,首先标记所有节点为未删除 依次扫描prufer 序列中的数,比如当前扫描到第k个数u,说明有一个叶子节点连到u,并在当前操作中被删除,找一个标号最小的未被标记为删除的且在prufer 序列第k个位置后未出现过的节点v,在u,v间连边并将v删除,反复操作,最后剩两个节点未被标记为删除,在它们之间连边,这样得到的一个图含有n-1条边则是一棵树

3. 一棵树N个结点,其Profer序列有N-2个位置,因此可以在这N-2个位置里面任何的填充1~N之间的数形成一个prufer序列,且一个prufer序列唯一的对应一颗生成树,于是完全图的最小生成树的数目为N^(N-2)
-------------------------------------------------------------------------------------------------------------------

Prufer Code(摘自JokerPark


这两天看了Prufer编码。意思就是把一棵n个节点并且带编号的无向树与一个n-2长度的数组建立双射。规则如下:

    (1)将树中与编号最小的叶节点相连的节点编号加入数组。

    (2)删去编号最小的叶节点。

    (3)重复第1个操作。直到树中只剩两个节点结束操作。

    这样就得到了一组数。

    通过Prufer编码得到的数组具有这些特性:

    1.一棵树对应唯一的一组数组。

    2.每个节点的标号出现在数组中的次数等于它的度数减1。(原树中的叶子节点不出现在数组中)

    优点:我了解了Prufer编码后,发现,可以对一个数组进行分析从而分析一棵无向树。这样就起到了降维(也许可以这么说吧。。。。。)的作用,可以直接利用组合数学的方法直观求解给定度数的不同无向树的种类。Amazing、、

    那么,对于一个长度为n-2的数组如何还原为一棵n个节点的无向带标号树呢?

    步骤如下:

    (1)确定每个标号所对应的点的度数。

    (2)从数组的头开始,依次向后。把当前数组中存的标号所对应的节点与当前n个节点中标号最小的叶子节点相连。

    (3)重复第二步骤,直到做了n-2遍。

    (4)将剩余的两点相连!

    我弱弱地想:在还原为树的过程中,每一次都要寻找标号最小的叶节点。可以用映射堆优化。

    建立一个堆,存储叶节点,以标号为比较的关键字。在做(2)步骤时,维护堆,同时删除连接的叶子节点。两个操作时间复杂度都为O(logN),询问只要O(1)。

 

    对于给定每个点度数的无向树,求不同树的总数的公式为:

    ans=Cn-2d1-1*Cn-2-d1-1),d2-1*…*Cdn-1dn-1=n-2)!/((d1-1)!*d2-1)!*…*dn-1)!)
-------------------------------------------------------------------------------------------------------------------


原创粉丝点击