【知识】Prufer 编码

news/2024/12/1 18:35:16/文章来源:https://www.cnblogs.com/fanrunze/p/18580160

Prufer 序列

Prufer 序列可以将一个带标号 \(n\) 个节点的树用 \([1, n]\) 中的 \(n-2\) 个整数表示,即 \(n\) 个点的完全图的生成树与长度为 \(n-2\),值域为 \([1, n]\) 的数列构成的双射。

Prufer 序列可以方便地解决一类树相关的计数问题,比如 凯莱定理\(n^{n-2}\) 个点的完全图的生成树有 \(n^{n-2}\) 个。

对树构造 Prufer 序列

Prufer 是这样构造的:

每次选择一个编号最小的叶节点并删掉它,然后在序列中记录下它连接到的那个节点。

重复 \(n-2\) 次后就只剩下两个节点,算法结束。

  • \(\mathcal{O}(n \log n)\) 显然,使用堆可以做到 \(\mathcal{O}(n \log n)\) 的复杂度。

  • \(\mathcal{O}(n)\) 使用一个指针代替堆找最小值,可以做到 \(\mathcal{O}(n)\) 的复杂度。

具体而言,指针指向编号最小的叶节点。每次删掉它之后,如果产生了新的叶节点且编号比指针指向的更小,则直接继续删掉,否则自增找到下一个编号最小的叶节点。

Prufer 序列的性质

从上述构造 Prufer 序列的过程可以看出 Prufer 序列具有以下两个性质:

  1. 在构造完 Prufer 序列后,原树中会剩下两个节点,其中一个一定是编号最大的点 \(n\)
  2. 每个节点在序列中出现的次数是其度数减 \(1\),因此没有出现的就是叶节点。

用 Prufer 序列构造树

根据 Prufer 序列的性质,我们可以得到原树上每个点的度数。

每次我们选择一个编号最小的度数为 \(1\) 的节点,与当前枚举到的 Prufer 序列的点连接,然后同时减掉两个点的度数。重复 \(n-2\) 次后就只剩下两个度数为 \(1\) 的节点,其中一个是 \(n\),把它们连接起来即可。

  • \(\mathcal{O}(n \log n)\) 同样地,显然,使用堆可以做到 \(\mathcal{O}(n \log n)\) 的复杂度。

  • \(\mathcal{O}(n)\) 类似地,使用一个指针代替堆找最小值,可以做到 \(\mathcal{O}(n)\) 的复杂度。

具体而言,指针指向编号最小的度数为 \(1\) 的节点。每次将它与当前枚举到的 Prufer 序列的点连接之后,如果产生了新的度数为 \(1\) 的节点且编号比指针指向的更小,则直接继续将它与下一个 Prufer 序列的点连接,否则自增找到下一个编号最小的度数为 \(1\) 的节点。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int N = 100010;int n, m;
int f[N], d[N], p[N];void tree2prufer()
{for (int i = 1; i < n; i ++ ){scanf("%d", &f[i]);d[f[i]] ++ ;}for (int i = 0, j = 1; i < n - 2; j ++ ){while (d[j]) j ++ ;p[i ++ ] = f[j];while (i < n - 2 && -- d[p[i - 1]] == 0 && p[i - 1] < j) p[i ++ ] = f[p[i - 1]];}for (int i = 0; i < n - 2; i ++ ) printf("%d ", p[i]);
}void prufer2tree()
{for (int i = 1; i <= n - 2; i ++ ){scanf("%d", &p[i]);d[p[i]] ++ ;}p[n - 1] = n;for (int i = 1, j = 1; i < n; i ++, j ++ ){while (d[j]) j ++ ;f[j] = p[i];while (i < n - 1 && -- d[p[i]] == 0 && p[i] < j) f[p[i]] = p[i + 1], i ++ ;}for (int i = 1; i <= n - 1; i ++ ) printf("%d ", f[i]);
}int main()
{scanf("%d%d", &n, &m);if (m == 1) tree2prufer();else prufer2tree();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/844682.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【牛客训练记录】华为杯2024年广东工业大学新生赛(同步赛)

训练情况赛后反思 组合数学还得加练,J题奇妙的乘法逆元预处理,开个unordered_map记忆化就过了?!,E题太头铁了,异或不算就直接交,F题又是急到没取模就直接交。 A题 字符串 Tomori 后面补上 Haruhikage。 #include <bits/stdc++.h> // #define int long long #defin…

攻防世界-baigeiRSA

一、题目 给了如下两个文件二、解题 1、查看代码发现就是简单的RSA加密算法,仔细分析一下发现flag就是明文,而要获得flag就要解密密文,但是代码中只提供了e。于是又去out文件翻了一下,常使用记事本打开,发现n和c已经给出,由于n的位数只有78个字符,可以尝试暴力分解因数2…

【TIA Portal V19软件下载与安装教程】

1、安装包 「TIA Portal V19(64bit).rar」 链接:https://pan.quark.cn/s/388931745834 提取码:VqMr 2、安装教程(建议关闭杀毒软件和系统防护) 1) 下载并解压安装包,右击执行NoRestart.bat文件2) 弹窗后,按任意键退出3) 安装Portal V19,管理员方式运…

《智能汽车传感器:原理设计应用》新书推荐

《智能汽车传感器:原理设计应用》新书推荐 由化学工业出版社资深编辑张海丽老师负责策划编辑。本书在京东、淘宝天猫、当当网上均有销售京东:https://search.jd.com/Search?keyword=%E6%99%BA%E8%83%BD%E6%B1%BD%E8%BD%A6%E4%BC%A0%E6%84%9F%E5%99%A8%EF%BC%9A%E5%8E%9F%E7%…

38. html_02

1. 标签的id属性和class属性 id 用于精确查找某个标签。 类似于标签的唯一标识符,用于在同一个页面上唯一标识一个特定的元素。每个id值在整个文档中都必须是唯一的,不能重复使用。通过id值,可以在JavaScript或CSS中引用特定标签,并对其进行操作或样式化。 class 类似于面向…

高级语言程序设计课程第九次个人作业(102400106刘鑫语)

这个作业属于哪个课程:https://edu.cnblogs.com/campus/fzu/2024C/ 这个作业要求在哪里: https://edu.cnblogs.com/campus/fzu/2024C/homework/13311 学号:102300106 姓名:刘鑫语 14.17.3;14.17.4 结构模板和数组,没有什么问题 14.17.5一开始定义days函数中试图访问month…

分布式训练

模型并行与数据并行 Parameter Server 同步更新: 在 work 比较多的情况下,parameter server 承受的压力会比较大,网络开销也大 异步更新: 1参数和更新用的梯度并不来自同一个迭代。用来更新的梯度可能是几步更新前的参数算出来的。 2参数的读取并没有加锁。这导致 worker 可…

宝塔安装thinkphp低版本路径不对

如果你在宝塔面板上安装了ThinkPHP低版本(例如ThinkPHP 5.0或更早版本),但遇到了路径问题,可以按照以下步骤进行排查和解决: 1. 检查网站根目录设置 确保你的网站根目录设置正确。通常,ThinkPHP项目的入口文件是 public 目录下的 index.php 文件。登录宝塔面板。 进入“网…

C#基础之集合讲解

目录1 集合1.1 数组1.1.1 简介1.1.2 声明使用1.1.2.1 声明 & 初始化1.1.2.2 赋值给数组1.1.2.3 访问数组元素1.1.3 多维数组1.1.3.1 声明1.1.3.2 初始化二维数组1.1.3.3 访问二维数组元素1.1.4 交错数组1.1.5 传递数组给函数1.1.6 Array1.1.6.1 简介1.1.6.2 属性1.1.6.3 方…

织梦网站关键词修改,如何优化DedeCMS的关键词设置

修改织梦网站(DedeCMS)的关键词设置可以通过以下步骤实现:登录管理后台:使用管理员账号登录DedeCMS管理后台。 进入SEO设置:导航至“系统” > “系统基本参数” > “SEO设置”。 修改关键词:在“关键词”字段中,输入新的关键词。 保存更改:确认无误后,保存修改。…

C#基础之不安全代码讲解

目录1 不安全代码1.1 简介1.2 指针变量1.3 编译不安全代码1.4 使用示例1.4.1 简单使用1.4.2 使用指针检索数据值1.4.3 传递指针作为方法的参数1.4.4 使用指针访问数组元素1.5 fixed1.5.1 为什么需要 fixed1.5.2 为什么 int *p 和 int[] p 是不同的类型1.5.3 示例1.6 stackalloc…