所谓 Prufer 序列,就是 Prufer 发明的序列。

(逃)

前言

优雅的神奇魔术。
看名字很高大难,但实际上是高大清(小清新)。
很简单的建立起树与序列之间的双射,且这个序列的性质非常良好,且这个序列的性质与度数密切相关。
能优雅简洁的证明一些恶心的结论。

注意! Prufer序列不考虑只有一个结点的树。

解析

定义

把一棵树转化为 Prufer 序列的流程如下:

  1. 找到当前度数为1且编号最小的点 xxx。
  2. 将 xxx 点删去,将唯一与 xxx 相连的点 fff (可以理解为以n作根情况下的“父亲”)加入 Prufer 序列。
  3. 将 fff 的度数减一。
  4. 不断执行 1-3,直到只剩下两个点。

最终我们得到的长度为 n−2n-2n−2 的序列即最终的 Prufer 序列。

性质

其有如下性质:

  1. 序列中的每个数都是 [1,n][1,n][1,n] 之间。
  2. 一个度数为 dxd_xdx​ 的点在序列中出现 dx−1d_x-1dx​−1 次。
  3. 最终剩下的两个点中必然有一个点为 nnn。

都较为显然。

把树转化为 Prufer 序列

利用 Prufer 序列的定义,开一个堆存当前的度数为1的点,即可 O(nlog⁡n)O(n\log n)O(nlogn) 的构造。
但可以做到线性。
维护一个指针 ppp,从1扫到n,表示当前编号最小的一度点。每次后移指针知道找到一个一度点,将其加入 Prufer 序列,如果父亲减完度数变成了一度点且编号小于 ppp 则将父亲加入序列,并递归的考虑祖父,否则直接忽略。
注意这么做最后会得到一个 n−1n-1n−1 的序列,因为最后会把和 nnn 相连的点也删去。把序列尾抹掉即可。

for(int i=1;i<n;i++){fa[i]=read();du[i]++;du[fa[i]]++;}for(int p=1;p<n;p++){if(du[p]>1) continue;q[++tot]=fa[p];int f=fa[p];--du[f];while(du[f]==1&&f<p){q[++tot]=fa[f];f=fa[f];--du[f];}}--tot;

把 Prufer 序列转化为树

利用 Prufer 序列的性质2,我们可以得到每个点的度数。
每次找到最小的一度点,它的父亲就是当前序列的队首元素,将其与队首连边,队首的度数减一,并后移队首指针。
和树转化为 Prufer 序列类似的,我们也可以维护一个指针 ppp 做到线性。
注意,由于 Prufer 序列的长度只有 n-2,我们必然只为 n-2 个结点分配了“父亲”(即连了n-2条边),最后我们最后找到那个没有被分配父亲的非 n 的点,将其与 n 相连即可。

for(int i=1;i<=n;i++) du[i]=1;for(int i=1;i<=n-2;i++){q[i]=read();++du[q[i]];}int pl=1;for(int p=1;p<n&&pl<=n-2;p++){if(du[p]>1) continue;int x=p;while(x<=p&&du[x]==1&&pl<=n-2){fa[x]=q[pl];du[q[pl]]--;x=q[pl];++pl;}}for(int i=1;i<n;i++) if(!fa[i]) fa[i]=n;

凯莱定理

通过上面的构造我们可以知道,有标号无根树和Prufer序列是双射关系
Prufer 序列的个数显然为 nn−2n^{n-2}nn−2 个,那么我们也就自然得出了凯莱定理

nnn 个结点的有标号无根树有 nn−2n^{n-2}nn−2 个。

模板:Prufer序列相关推荐

  1. 解题报告(八) prufer 序列与 Cayley 公式(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  2. 最小生成树、矩阵树定理、Prufer序列总结

    Kruskal算法 按边权排序,从小到大合并不在同一集合两点即可 Prim算法 每次加入一个到当前已选点集最近的点 P2619 [国家集训队]Tree I 考虑二分,每次给白边加上一个mid,通过这种 ...

  3. Prufer序列相关

    最近做到一些题,用到了Prufer序列,挺有用的,在这里学习一下. 描述 Prufer数列是无根树的一种数列,通过一个Prufer序列可以唯一表示一棵顶点带标号的无根树,点数为n的树转化来的Prufe ...

  4. [XXSY] 构树(prufer序列,树上连通块DP)

    传送门 CayleyCayleyCayley公式:一个完全图有nn−2n^{n-2}nn−2棵无根生成树(可用prufer序列证明) 扩展CayleyCayleyCayley公式:被确定边分为大小为a ...

  5. 曼哈顿距离与切比雪夫距离的转化及prufer序列

    目录 曼哈顿距离与切比雪夫距离的相互转化 prufer序列 1. 曼哈顿距离 与 切比雪夫距离 的相互转化 曼哈顿距离 |x1−x2|+|y1−y2|=max(x1−x2+y1−y2,x1−x2−y1 ...

  6. Prufer序列 生成树定理

    Description 在图论中,树的定义是连通且无环的无向图.对于一棵有 nn 个节点且节点从 11 到 nn 编号的树,它的 Prufer 序列是一个唯一的长为 n−2n−2 的标号序列. Pru ...

  7. 树的计数(prufer序列 或 purfer序列)

    题解 首先我们要知道一条性质,prufer序列中的某个点出现次数为该点在树中度数-1 感性理解一下,其实按照prufer序列求法自己推一下就出来了 设题目里给的度为$d[]$ 先将所有的d-- 然后按 ...

  8. 【XSY2519】神经元 prufer序列 DP

    题目描述 有\(n\)点,每个点有度数限制,\(\forall i(1\leq i\leq n)\),让你选出\(i\)个点,再构造一棵生成树,要求每个点的度数不超过度数限制.问你有多少种方案. \( ...

  9. 【XSY1295】calc n个点n条边无向连通图计数 prufer序列

    题目大意 求\(n\)个点\(n\)条边的无向连通图的个数 \(n\leq 5000\) 题解 显然是一个环上有很多外向树. 首先有一个东西:\(n\)个点选\(k\)个点作为树的根的生成森林个数为: ...

最新文章

  1. 决策智能(Decision Intelligence)二三事
  2. oracle select 行数据_【赵强老师】什么是Oracle的数据字典?
  3. eclipse maven jetty插件方式启动项目
  4. Codeforces Round #703 (Div. 2) 题解
  5. python存储和读取数据时出现错误_python读取json文件存sql及codecs读取大文件问题...
  6. 二叉树题目----6 二叉树的最近公共祖先 AND 二叉树搜索树转换成排序双向链表
  7. 近似算法的近似率_选择最佳近似最近算法的数据科学家指南
  8. SparkSQL-从0到1认识Catalyst
  9. 【Flink】Flink Not all required tasks are currently running
  10. 前端开发者正在被迫成为全栈开发人员
  11. 【Pygame】屏幕图形绘制
  12. 四、BDB JE学习(对java中内置对象的存储)
  13. 第九篇 设计模式之装饰模式
  14. Fluent.TGrid.v4.0.16
  15. jmeter使用心得(一)
  16. 如何判断矩阵的谱半径 C语言,矩阵谱半径
  17. labview 编程样式_LabVIEW编程实例:一个简单通用的“关于”对话框模板实现
  18. 【产品】蓝绿发布、滚动发布和灰度发布对比
  19. 【花雕动手做】有趣好玩的音乐可视化系列小项目(22)--LED无限魔方
  20. codeforces 1238

热门文章

  1. php中怎样表示组合框,php – 如何实现动态组合框选择系统
  2. 信号转化java_Java基础知识回顾-7
  3. formula 返回list_python正则实现计算器功能
  4. 连接mysql数据库2013_使用VS2013 + EF6 + .NET4.5 连接Mysql数据库
  5. 海德汉编程详细手册_UG编程海德汉系统螺旋铣孔最后一刀欠切解决方案
  6. python数据分析与展示 pdf课件_python数据分析与展示 课件 相关实例(示例源码)下载 - 好例子网...
  7. java代码实现链表_java单链表代码实现
  8. jsoup 获取html中body内容_jsoup实现java抓取网页内容
  9. java 数组 树_java使用顺序数组实现二叉树
  10. java发送会议邀请邮件模板_Spring 发送邮件 HTML邮件