首页 > 其他分享 >Prufer 序列 - 无根树的序列化

Prufer 序列 - 无根树的序列化

时间:2023-09-06 20:45:01浏览次数:44  
标签:int prufer pos 序列 无根树 序列化 Prufer 节点

定义

一种将带标号的树用一个唯一的整数序列表示的方法。
Prufer 序列可以把一颗带标号的 \(n\) 个节点的树序列化为一个长度为 \(n - 2\) 的唯一的序列。
也就相当于完全图的生成树与数列之间的双射

构造方式

每次选择一个编号最小的叶节点并删掉它,然后在序列中记录下它连接到的那个节点。
重复 \(n - 2\) 次如上操作,此时树上只剩 \(2\) 个节点,算法结束。
如果使用优先队列来构造,时间复杂度显然是 \(O(n\log n)\)。
可以使用指针来构造,将时间复杂度降低至 \(O(n)\)。
首先找到编号最小的,度数为 \(1\) 的叶子节点,指针 \(p\) 指向它,将它删除。
如果删除了这个节点后,它的父亲节点的编号比它小并且父亲节点的度数也变成了 \(1\),那么此时这个节点一定是编号最小的叶子节点,删除它即可,同时不断往上删除,注意在这个过程中 \(p\) 并不进行移动。
否则的话,继续让 \(p\) 自增,找到下一个编号最小的叶子节点即可。
每条边在删度数的时候最多被访问一次,而指针最多遍历每个结点一次,因此复杂度是 \(O(n)\) 的。

性质

Prufer 序列具有以下性质:

  • 构造完 Prufer 序列后剩下的两个节点其中一个是编号最大的点 \(n\)。
  • 每个节点出现的次数是度数减一。
  • 没有出现在 Prufer 序列里的节点的就是叶子节点。

树的还原

通过 Prufer 序列还原树的方法和构造它的方法差不多。
Prufer 序列告诉了我们每个节点的度数,我们可以找到编号最小的度数为 \(1\) 的节点,根据构造方法来看,它一定和 Prufer 序列的第一个元素相连接。从这里就大概和 Prufer 序列的构造方法几乎一样了。

Cayley 公式

完全图 \(K_n\) 有 \(n^{n - 2}\) 棵生成树。
任意一个长度为 \(n - 2\) 的值域 \([1, n]\) 的整数序列都可以通过 Prufer 序列双射对应一个生成树,于是方案数就是 \(n^{n - 2}\)。

模板题:

点击查看 Prufer 序列 代码
#define int ll

int n, m;
const int MAXN = 5e6 + 5;
int fa[MAXN], prufer[MAXN], deg[MAXN];

void solve_prufer() {
	rep (i, 1, n - 1) cin >> fa[i], deg[fa[i]]++;
	int pos = 1;
	rep (i, 1, n - 2) {
		while (deg[pos]) pos++;
		prufer[i] = fa[pos];
		while (i <= n - 2 && !--deg[prufer[i]] && prufer[i] < pos)
			prufer[i + 1] = fa[prufer[i]], i++;
		pos++;
	}
	int ans = 0;
	rep (i, 1, n - 2) ans ^= i * prufer[i];
	cout << ans;
}

void solve_father() {
	rep (i, 1, n - 2) cin >> prufer[i], deg[prufer[i]]++;
	prufer[n - 1] = n;
	int pos = 1;
	rep (i, 1, n - 1) {
		while (deg[pos]) pos++;
		fa[pos] = prufer[i];
		while (i <= n - 1 && !--deg[prufer[i]] && prufer[i] < pos)
			fa[prufer[i]] = prufer[i + 1], i++;
		pos++;
	}
	int ans = 0;
	rep (i, 1, n - 1) ans ^= i * fa[i];
	cout << ans;
}

标签:int,prufer,pos,序列,无根树,序列化,Prufer,节点
From: https://www.cnblogs.com/Ark-Aak/p/prufer-sequence.html

相关文章

  • DRF----限流、序列化、视图、条件搜索
    1.4djangorestframework(中)drf内置了很多便捷的功能,在接下来的课程中会给大家依次讲解下面的内容:快速上手请求的封装版本管理认证权限限流序列化视图条件搜索分页路由解析器 6.限流限流,限制用户访问频率,例如:用户1分钟最多访问100次......
  • .NET 序列化生成 JavaScriptSerializer Poc
    dot.NET安全矩阵星球群有位师傅问起如何才能生成和ysoserial一样的JavaScriptSerializer序列化poc,同Json.NET一样序列化使用了ObjectDataProvider类,ObjectInstance属性绑定实例化的Process对象,这里没有使用MethodParameters属性传递参数,而是使用ProcessStartInfo类FileName和Argum......
  • Java反序列化:CommonsCollections5调试分析
    基础知识1.BadAttributeValueExpException相关源码可以看到这个异常类的支持序列化和反序列化,同时在反序列化readObject函数中会涉及到toString函数publicclassBadAttributeValueExpExceptionextendsException{/*Serialversion*/privatestaticfinal......
  • weblogic-10.3.6-'wls-wsat'-XMLDecoder反序列化漏洞-(CVE-2017-10271)
    目录1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描nacsweblogicScanner3、漏洞验证说明内容漏洞编号CVE-2017-10271漏洞名称Weblogic<10.3.6'wls-wsat'XMLDecoder反序列化漏洞(CVE-2017-10271)漏洞评级高危影响范围10.3......
  • typecho_v1.0-14.10.10_反序列化漏洞复现
    目录漏洞利用GetShell下载链接:https://pan.baidu.com/s/1z0w7ret-uXHMuOZpGYDVlw提取码:lt7aTypecho-反序列化漏洞大佬博客Typechoinstall.php存在的反序列化漏洞首页漏洞点:/install.php?finish=漏洞利用漏洞利用脚本phpinfo()信息<?php//typecho_1.0(14.10.......
  • JAVA反序列化- Shiro反序列化
    环境搭建shiro源码,导入源码后,idea从shiro/samples/web进入gitclonehttps://github.com/apache/shiro.gitcdshirogitcheckoutshiro-root-1.2.4编辑shiro/samples/web目录下的pom.xml,将jstl的版本修改为1.2。默认没有版本,会在解析时报错。<dependency><groupId>ja......
  • 安全攻防丨反序列化漏洞的实操演练
    通过实操演练,深入浅出、快速吃透反序列化漏洞的根本原理。搞懂了攻击本质原理,才知道代码怎么写才安全。1.基本概念序列化:将内存对象转化为可以存储以及传输的二进制字节、xml、json、yaml等格式。反序列化:将虚化列存储的二进制字节、xml、json、yaml等格式的信息重新还原转化为对......
  • 精简深拷贝ArrayList实例(包括递归和序列化方法)
    作者fbysss关键字:深拷贝,序列化前言:     日前一哥们问我一个有关多层ArrayList拷贝的问题,我帮他写了一个例程,感觉以后用得着,便放上来了。如果要在自身类中加入Clone功能,需要implementsICloneable接口,然后用下面的相应代码重写clone方法即可。源代码:packagecom.sss.t......
  • 序列化和反序列化二叉搜索树
    设计一个算法来序列化和反序列化二叉搜索树对序列化/反序列化算法的工作方式没有限制您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。1.非递归先序遍历+编码classCodec{public://Encodesatreetoasinglestring.......
  • 2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数
    2023-09-03:用go语言编写。给你一个n个节点的无向无根树,节点编号从0到n-1给你整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间有一条边。再给你一个长度为n的数组coins,其中coins[i]可能为0也可能为1,1表示节......