首页 > 其他分享 >Prufer序列

Prufer序列

时间:2024-04-17 16:44:19浏览次数:17  
标签:度数 结点 序列 Prufer 节点 deg

Prufer序列通常在图的计数问题中比较常用。

Prufer序列的构造方法:(图片源自oiwiki)

具体操作步骤:先找到叶子结点中编号最小的节点,然后删除。在Prufer序列中的元素就是每次删除的节点的父节点。由于最后操作必然会剩下两个节点,两个节点都是叶子结点,于是操作完毕,最终构造出的Prufer序列有n-2个元素。

Prufer序列有以下几个性质:
1.假设节点u的度数为deg[u],那么节点u在Prufer序列中的出现次数为deg[u]-1。
2.在构造完原树之后会剩下2个节点,其中一个必然是编号最大的节点。
3.一个Prufer序列对应的树唯一,一颗树的Prufer序列唯一。

一些由基本性质扩展出来的性质:
1.对于一个n个节点的完全图,其无根树共有\(n^{{n-2}}\)种情况(Cayley公式)
2.对于一个n个节点的完全图,其无根树共有\(n^{{n-1}}\)种情况(因为每个点都能为根)
3.已知每个点的度数,其生成树共有\(\frac{(n-2)!}{\prod_{1}^{n}(deg[i]-1)!}\)种情况。

P6086 【模板】Prufer 序列:https://www.luogu.com.cn/problem/P6086
模版题。
1.构造Prufer序列的线性做法的大致思路:
从1到n-1遍历每个点,当发现当前点是叶子结点(度数为1),进行操作。首先将其父节点加入Prufer序列中,将当前节点删除并将父节点的度数-1.如果父节点因当前删除操作而成为叶子结点,我们比较父节点和当前节点的大小。若父节点比当前节点更小则下一步操作必删父节点,继续递归操作即可。否则继续按照顺序遍历节点,直到找到叶子结点再进行删点操作。

void del(int x,int y)//x是当前点的编号,y是当前的编号大小上限
{
    pru[++tot]=x;//prufer 序列
    if(--deg[fa[x]]==1&&fa[x]<y) add(fa[x],y);//递归加点 
}
for(int i=1;i<=n;i++)
{
    if(deg[i]==1) del(i,i);
}

2.从Prufer序列还原树的操作 线性做法大致思路:
我们知道每个点在Prufer序列中的的出现次数是deg[u]-1,那么通过每个点的出现次数可以知道度数,知道度数了之后可以判断是否为叶子结点。
我们遍历Prufer序列中的每一个元素,统计其出现次数。再从1到n-1遍历每个点,当发现其出现次数为0说明是叶子结点,那么按照Prufer序列中从前往后的顺序依次还原其父节点。假如父节点的编号比当前节点更小那么下一个必定还原父节点,实际上就是把生成Prufer序列的操作反过来了。

void add(int x,int y)
{
    fa[x]=pru[++tot];
    if(--cnt[fa[x]]==0&&fa[x]<y) add(fa[x],y);
}
for(int i=1;i<=n;i++)
{
    if(cnt[i]==0) add(i,i);
}

标签:度数,结点,序列,Prufer,节点,deg
From: https://www.cnblogs.com/captainfly/p/18141138

相关文章

  • 一种融合指代消解序列标注方法在中文人名识别上的应用(上)
    技术领域自然语言处理领域。应用场景:适用于自然语言处理领域,通过命名实体识别(NamedEntityRecognition,NER),准确识别实体。依托自然语言处理领域,基于人民日报数据及构造的舆情公告数据,提出一种融合指代消解的序列标注方法来改进人名识别。解决的问题:实体包括人名、地......
  • 西门子PLC数据类型1-位、位序列、整数、浮点数、日期时间
     本文摘于西门子官网内容一、位、位序列、整数、浮点数、日期时间基本数据类型:包括位、位序列、整数、浮点数、日期时间。此外字符也属于基本数据类型,请参见文档 String 与 WString。此外BCD码虽然不属于数据类型,但也是一种数字表示方式。1.1位和位序列注意:虽然位......
  • fastjson 1.2.24 反序列化导致任意命令执行漏洞复现
    前置知识今天复现了常见的fastjson反序列化漏洞,了解该漏洞需要一些前置的知识,这里总结一下:Fastjsonfastjson是一个Java的库,可以将Java对象转换为Json字符串,也可以将Json字符串转换为Java对象,Fastjson也可以操作一些Java中的对象。JNDIJNDI(JavaNamingandDirectoryInterf......
  • python 序列类型 元组
    元组定义元组是不可变序列,通常用于储存异构数据的多项集(例如由enumerate()内置函数所产生的二元组)。元组也被用于需要同构数据的不可变序列的情况(例如允许存储到set或dict的实例)。元组是Python中的一种数据结构,类似于列表,但是元组是不可变的,意味着一旦创建,元组内的元素......
  • BZOJ 4403序列统计
    BZOJ4403序列统计解析序列满足单调不降序列,所以每个数可以选多次,我们可以把不同位置的同一个数看成多个,这样把区间为\([L,R]\)中的每一个数加上\(i\),得到的区间大小为\([L+1,R+n]\),也就是从\(R-L+n\)个数中选\(n\)个。\[\begin{aligned}&{\sum^n_{i=1}C^{i......
  • C3P0反序列化链分析
    前言C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。使用它的开源项目有Hibernate、Spring等。之前有接触到过,但是没有深入了解,像之前学二次反序列化时,WrapperConnectionPoolDataSource就是C3P0的环境搭建<dependency><groupId>com.......
  • 一种融合指代消解序列标注方法在中文人名识别上的应用(下)
    二、使用了BERT模型和指代消解算法:加入BERT语言预处理模型,获取到高质量动态词向量。融入指代消解算法,根据指代词找出符合要求的子串/短语。【2】融入指代消解算法,根据指代词找出符合要求的子串/短语指代消解算法如图2所示,简单来说,就是考虑文档中子串/短语以及学习子......
  • DRF之序列化类介绍及使用
    一、序列化类1、介绍序列化组件在DRF中扮演着重要的角色,帮助开发者轻松地定义数据的序列化和反序列化过程,同时提供了数据验证、字段定义、嵌套序列化等功能。通过使用序列化组件,您可以更好地控制API的数据输入和输出,确保数据的有效性和一致性。serializers.Serializer是基......
  • Kryo反序列化链分析
    前言Kryo是一个快速序列化/反序列化工具,依赖于字节码生成机制(底层使用了ASM库),因此在序列化速度上有一定的优势,但正因如此,其使用也只能限制在基于JVM的语言上。Kryo序列化出的结果,是其自定义的,独有的一种格式。由于其序列化出的结果是二进制的,也即byte[],因此像redis这样可以存......
  • 如何使用groovy反序列化json
    使用Groovy反序列化JSON可以通过以下步骤实现:导入相关的Groovy库:在Groovy脚本或Groovy项目中,首先需要导入相关的Groovy库,以便使用JSON反序列化的功能。可以使用以下代码导入库:importgroovy.json.JsonSlurper复制创建JsonSlurper对象:JsonSlurper是Groovy提供的一个用于解......