当前位置: 首页 > news >正文

【学习笔记】Prufer序列

Prufer序列

起源于对 C a y l e y Cayley Cayley定理的证明,但是其功能远不止于此
现在考虑将一棵n个节点的树与一个长度为n-2的prufer序列构造对应关系

  • T r e e − > P r u f e r : Tree->Prufer: Tree>Prufer:

    ①从树上选择编号最小的叶子节点,序列的下一位为其父节点的编号。

    ②删去该叶子节点。

    ③重复①和②,直到树只剩下两个节点,此时序列的长度刚好为 n−2 。

  • P r u f e r — > T r e e : Prufer—>Tree: Prufer>Tree:

    ①选择编号最小的叶子节点(即未出现在序列中的节点),其父节点就是序列的第 i ( i 初始为1)个元素。

    ②由性质可得,其父节点的度数为其出现次数+1。将该叶子节点删去,其父节点度数-1。若度数变成1,则父节点也成为叶子节点。

    ③将 i 加一,然后重复①和②,直到序列的每一个元素都使用完毕。

ll p[N];
ll d[N];//度数
ll f[N];//连边
ll ans=0;
void Prufer_To_Tree(ll n)
{//f记录1-n-1的连边情况for(int i=1;i<=n-2;++i) cin>>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];//把最小的叶往prufer序列第一个点上接 对应减掉度数while(i<n&&!--d[p[i]]&&p[i]<j) f[p[i]]=p[i+1],i++;//如果序列第一个点减掉度数后产生了新的更小的叶 就往序列下一个点上接}for(int i=1;i<=n;++i) ans^=1ll*i*f[i];
}
void Tree_To_Prufer(ll n)
{for(int i=1;i<n;++i) cin>>f[i],d[f[i]]++;for(int i=1,j=1;i<=n-2;++i,++j){while(d[j]) j++;p[i]=f[j];while(i<=n-2&&!--d[p[i]]&&p[i]<j) p[i+1]=f[p[i]],i++;}for(int i=1;i<=n-2;++i) ans^=1ll*i*p[i];
}

由此我们发现两者是一一对应的,也就是双射,所以大小为n的有标号无根树的个数等于长度为 n − 2 n-2 n2的prufer序列的个数,自然为 n n − 2 n^{n-2} nn2 C a y l e y Cayley Cayley定理得证

Prufer序列的性质

由Prufer序列构造的过程,我们可以发现其具有两个显而易见的性质。

  • 构造完后剩下的两个节点里,一定有一个是编号最大的节点。

  • 对于一个 n 度的节点,其必定在序列中出现 n−1 次。因为每次删去其子节点它都会出现一次,最后一次则是删除其本身。一次都未出现的是原树的叶子节点。

应用

1、无向完全图的不同生成树数:

n n − 2 n^{n−2} nn2

2、 n 个点的无根树计数:

同上问题。

3、 n 个点的有根树计数:

对每棵无根树来说,每个点都可能是根,故总数为 n n − 2 × n = n n − 1 n^{n−2}×n=n^{n−1} nn2×n=nn1

4、 n 个点,每点度分别为 d i d_i di 的无根树计数:

显然就是一个多重集,答案为 ( n − 2 ) ! ∏ i = 1 n d i − 1 \frac{(n-2)!}{\prod_{i=1}^{n}d_i-1} i=1ndi1(n2)!

5、 有标号的完全二分图 K n , m K_{n,m} Kn,m的生成树个数为 n m − 1 m n − 1 n^{m-1}m^{n-1} nm1mn1:

考虑将其生成树的prufer序列按照原本顺序分成 f i ≤ n , f i > n f_i\leq n,f_i>n fin,fi>n两部分。

对于 f i ≤ n f_i\leq n fin的部分,一定是删去某个标号 > n >n >n的点之后留下 f i f_i fi的,因为这是一张二分图。所以该部分的点一定恰好有 m − 1 m-1 m1个(右部有m个点,整张图删完之后一定在左右部各留下一个点,所以右部一共要删去 m − 1 m-1 m1个点)

f i > n f_i>n fi>n部分同理。

所以此时还是可以用一个prufer序列与合法生成树对应,故方案数为 n m − 1 m n − 1 n^{m-1}m^{n-1} nm1mn1

Tips:

一般要特判n=1的情况

例题

Valuable Forests

大意:

定义一个树的权值为其所有节点的度数的平方和,森林的权值为所有树的权值和。求大小为n的所有有标号森林的权值和

思路:

f i f_i fi表示大小为i的所有有标号森林的权值和,也就是答案

考虑对于最后一个点所在的树的大小为k的情况

f n = ∑ k = 1 n ( n − 1 k − 1 ) f n − k m k + ( n − 1 k − 1 ) g k h n − k f_n=\sum_{k=1}^{n}\binom{n-1}{k-1}f_{n-k}m_k+\binom{n-1}{k-1}g_kh_{n-k} fn=k=1n(k1n1)fnkmk+(k1n1)gkhnk

其中 m i m_i mi表示大小为 i i i的有标号无根树的个数, g i g_i gi表示大小为 i i i的所有有标号无根树的权值和, h n − k h_{n-k} hnk表示大小为 n − k n-k nk的森林的数量。 ( n − 1 k − 1 ) \binom{n-1}{k-1} (k1n1)是因为枚举的k的含义是n所在树的大小,我要从剩下 n − 1 n-1 n1个点里面选 k − 1 k-1 k1个点。如果不这样枚举的树的组合就会算重。

m n m_n mn很简单: n = 1 n=1 n=1 m 1 = 1 m_1=1 m1=1,否则 m n = n n − 2 m_n=n^{n-2} mn=nn2

对于 g n g_n gn,我们枚举所有度数为i的贡献

转化到prufer序列中看这个问题,度数为i,表示出现了 i − 1 i-1 i1次,所以强制选定对应的数字以及位置,剩下的 n − 1 n-1 n1个数随便放

g n = ∑ i = 1 n − 1 i 2 n ( n − 2 i − 1 ) n − 1 n − 1 − i g_n=\sum_{i=1}^{n-1}i^2n\binom{n-2}{i-1}{n-1}^{n-1-i} gn=i=1n1i2n(i1n2)n1n1i

h n h_n hn的更新思路和 f f f差不多,枚举最后一个点所在的树的大小即可

h n = ∑ i = 1 n ( n − 1 i − 1 ) h n − i m i h_n=\sum_{i=1}^{n}\binom{n-1}{i-1}h_{n-i}m_i hn=i=1n(i1n1)hnimi

cf 156D

大意:

给定n个点以及m条连边,记最少添加T条边使得整张图连通,问有多少种恰好添加T条边的方案使得图连通

思路:

记当前连通块个数为k,则T=k-1

对于每一个连通块,其大小为 a i a_i ai,如果其度数为 d i d_i di的话,我们可以在以连通块为单位的情况下得到生成树个数为 ( k − 2 d 1 − 1 , d 2 − 1... d k − 1 ) \binom{k-2}{d1-1,d2-1...d_k-1} (d11,d21...dk1k2)

对于每一个连通块,固定连边的标号顺序(比如第1条边来自标号最小的连通块,依次类推),那么此时总方案数为 ( k − 2 d 1 − 1 , d 2 − 1... d k − 1 ) ∗ ∏ i = 1 k a i d i \binom{k-2}{d1-1,d2-1...d_k-1}*\prod_{i=1}^{k}a_i^{d_i} (d11,d21...dk1k2)i=1kaidi,因为每一条边都可以有 a i a_i ai种选择

所以答案为 ∑ ∑ d i = k − 2 ( k − 2 d 1 , d 2... d k ) ∗ ∏ i = 1 k a i d i + 1 = ∑ ∑ d i = k − 2 ( k − 2 ) ! ∏ i = 1 k d i ! ∗ ∏ i = 1 k a i d i + 1 \sum_{\sum d_i=k-2}\binom{k-2}{d1,d2...d_k}*\prod_{i=1}^{k}a_i^{d_i+1}=\sum_{\sum d_i=k-2}\frac{(k-2)!}{\prod_{i=1}^{k} d_i!}*\prod_{i=1}^{k}a_i^{d_i+1} di=k2(d1,d2...dkk2)i=1kaidi+1=di=k2i=1kdi!(k2)!i=1kaidi+1
= ( k − 2 ) ! ∏ i = 1 k a i ( ∑ ∑ i = 1 k d i = k − 2 ∏ i = 1 k a i d i d i ! ) =(k-2)!\prod_{i=1}^{k} a_i(\sum_{\sum_{i=1}^{k} d_i=k-2}\prod_{i=1}^{k}\frac{a_i^{d_i}}{d_i!}) =(k2)!i=1kai(i=1kdi=k2i=1kdi!aidi)

注意到 ( k − 2 ) ! ∏ i = 1 k a i (k-2)!\prod_{i=1}^{k} a_i (k2)!i=1kai是一个常数,我们只用看后面

记生成函数 f x = ∑ i = 0 inf ⁡ x i i ! = e x f_x=\sum_{i=0}^{\inf}\frac{x_i}{i!}=e^x fx=i=0infi!xi=ex

不难发现后面其实是k个函数 f a i f_{a_i} fai的卷积的某一项,故后面部分的答案为 [ x k − 2 ] ∏ i = 1 k e a i x = [ x k − 2 ] e n x = n k − 2 ( k − 2 ) ! [x^{k-2}]\prod_{i=1}^{k}e^{a_ix}=[x^{k-2}]e^{nx}=\frac{n^{k-2}}{(k-2)!} [xk2]i=1keaix=[xk2]enx=(k2)!nk2

所以最终答案为 n k − 2 ∏ i = 1 k a i n^{k-2}\prod_{i=1}^{k}a_i nk2i=1kai

相关文章:

【学习笔记】Prufer序列

Prufer序列 起源于对 C a y l e y Cayley Cayley定理的证明&#xff0c;但是其功能远不止于此 现在考虑将一棵n个节点的树与一个长度为n-2的prufer序列构造对应关系 T r e e − > P r u f e r : Tree->Prufer: Tree−>Prufer: ①从树上选择编号最小的叶子节点&#x…...

由于找不到msvcr110.dll的5种解决方法

在使用电脑的过程中&#xff0c;我们可能会遇到一些问题&#xff0c;比如打开软件时提示找不到 msvcr110.dll 文件丢失。这通常意味着该文件已被删除或损坏&#xff0c;导致程序无法正常运行。本文将介绍几种解决方案&#xff0c;帮助您解决这个问题。 首先&#xff0c;我们需…...

最长连续递增子序列

给定一个顺序存储的线性表&#xff0c;请设计一个算法查找该线性表中最长的连续递增子序列。例如&#xff0c;(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。 输入格式: 输入第1行给出正整数n&#xff08;≤105&#xff09;&#xff1b;第2行给出n个整数&#xff0c;…...

Java学习星球,十月集训,五大赛道(文末送书)

目录 什么是知识星球&#xff1f;我的知识星球能为你提供什么&#xff1f;专属专栏《Java基础教程系列》内容概览&#xff1a;《Java高并发编程实战》、《MySQL 基础教程系列》内容概览&#xff1a;《微服务》、《Redis中间件》、《Dubbo高手之路》、《华为OD机试》内容概览&am…...

前端VUE---JS实现数据的模糊搜索

实现背景 因为后端实现人员列表返回&#xff0c;每次返回的数据量在100以内&#xff0c;要求前端自己进行模糊搜索 页面实现 因为是实时更新数据的&#xff0c;就不需要搜索和重置按钮了 代码 HTML <el-dialogtitle"团队人员详情":visible.sync"centerDi…...

Android Studio 的android.jar文件在哪儿

一般在&#xff1a;C:\Users\admin\AppData\Local\Android\Sdk\platforms\android-33下&#xff08;不一定是33&#xff0c;这个得看你Android Studio->app->builde.gradle的targetSdk是多少&#xff09; 怎么找&#xff1a; 1.打开Android Studio 粘贴地址后&#xff0…...

Elasticsearch 部署学习

文章目录 Elasticsearch 部署学习1. 单节点部署 elasticsearch1.1 部署 jdk1.2 下载 elasticsearch1.3 上传文件并修改配置文件1.4 启动1.5 问题总结1.6 浏览器验证 2. 集群部署 elasticsearch3. 常用命令4. Elasticsearch kibana安装:one: 参考部署文档:two: 下载对应版本的安…...

nodejs 如何在npm发布自己的包 <记录>

一、包结构 必要结构&#xff1a; 一个包对应一个文件夹&#xff08;文件夹名不是包名&#xff0c;但最好与包名保持一致&#xff0c;包名以package.json中的name为主&#xff09;包的入口文件index.js包的配置文件package.json包的说明文档README.md 二、需要说明的文件 1.配…...

移植RTOS的大体思路

最首先当然是去官网看看是不是已经支持目标芯片啦&#xff0c;没有的话&#xff0c;就需要自己手动移植了 获取源码 一般可以从rtos官网或者GitHub上获取源码 确认源码结构 这种有官方文档说明&#xff0c;需要修改的一般都是BSP和libcpu相关文件夹中的内容 CPU架构移植 …...

FPGA到底是什么?

首先只是凭自己浅略的了解&#xff0c;FPGA好像也是涉及到了开发板&#xff0c;单片机之类的东西&#xff0c;和嵌入式十分相似&#xff0c;但是比嵌入式更高级的东西。 肯定有很多小伙伴如我一样&#xff0c;只是听说过FPGA&#xff0c;听别人说的传呼其神&#xff0c;那么它到…...

算法-单词搜索 II

算法-单词搜索 II 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/word-search-ii/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 DFS 2.1 解题思路 每个格子往上下左右四个方向DFS&#xff0c;拼接后的单词如果在答案集中&…...

怒刷LeetCode的第15天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;哈希表双向链表 方法二&#xff1a;TreeMap 方法三&#xff1a;双哈希表 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;二分查找 方法二&#xff1a;线性搜索 方法三&#xff1a;Arrays类的b…...

Android开发MVP架构记录

Android开发MVP架构记录 安卓的MVP&#xff08;Model-View-Presenter&#xff09;架构是一种常见的软件设计模式&#xff0c;用于帮助开发者组织和分离应用程序的不同组成部分。MVP架构的目标是将应用程序的业务逻辑&#xff08;Presenter&#xff09;、用户界面&#xff08;V…...

day2作业

1&#xff0c;输入两个数&#xff0c;完成两个数的加减乘除 #输入两个数&#xff0c;完成两个数的加减乘除 num1int(input("请输入第一个数:")) num2int(input("请输入第二个数:")) print(str(num1)str(num2)str(num1num2)) print(str(num1)-str(num2)str…...

Python办公自动化之Word

Python操作Word 1、Python操作Word概述2、写入Word2.1、标题2.2、章节与段落2.3、字体与引用2.4、项目列表2.5、分页2.6、表格2.7、图片3、读取Word3.1、读取文档3.2、读取表格4、将Word表格保存到Excel5、格式转换5.1、Doc转Docx5.2、Word转PDF1、Python操作Word概述 python-d…...

力扣26:删除有序数组中的重复项

26. 删除有序数组中的重复项 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 …...

基于C#的AE二次开发之IQueryFilter接口、ISpatialFilter接口、IQueryDef 接口的查询接口的介绍

一、开发环境 开发环境为ArcGIS Engine 10.2与Visual studio2010。在使用ArcEngine查询进行查询的时候主要使用三种查询接口IQueryFilter&#xff08;属性查询&#xff09; 、ISpatialFilter&#xff08;空间查询&#xff09; 、IQueryDef &#xff08;多表查询&#xff09; 那…...

Oracle 11g RAC部署笔记

搭了三次才搭好&#xff0c;要记录一下。 1. Oracle 11g RAC部署的相关步骤以及需要的包&#xff0c;可以参考这里。 Oracle 11g RAC部署_12006142的技术博客_51CTO博客Oracle 11g RAC部署&#xff0c;Oracle11gRAC部署操作环境&#xff1a;CentOS7.4Oracle11.2.0.4一、主机网…...

Redis 字符串操作实战(全)

目录 SET 存入键值对 SETNX SETEX SETBIT SETRANGE MSET 批量存入键值对 MSETNX PSETEX BITCOUNT 计算值中1的数量 BITOP 与或非异或操作 DECR 减1 DECRBY APPEND 追加 INCR 自增 INCRBY INCRBYFLOAT GET 取值 GETBIT GETRANGE GETSET 取旧值赋新值 MGET …...

python LeetCode 88 刷题记录

题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合并…...

基于 Socket 网络编程

基于 Socket 网络编程 前言一、基于Socket的网络通信传输&#xff08;传输层&#xff09;二、UDP 的数据报套接字编程1、UDP 套接字编程 API2、使用 UDP Socket 实现简单通信 三、TCP 流套接字编程1、TCP 流套接字编程 API2、使用 TCP Socket 实现简单通信3、使用 Tcp 协议进行…...

关于C#.Net网页跳转的7种方法

一、目前在ASP.NET中页面传值共有这么几种方式&#xff1a;1.Response.Redirect("http://www.hao123.com",false); 目标页面和原页面可以在2个服务器上&#xff0c;可输入网址或相对路径。后面的bool值为是否停止执行当前页。 跳转向新的页面&#xff0c;原窗口被代…...

使用acme.sh申请免费ssl证书(Cloudflare方式API自动验证增加DNS Record到期证书到期自动重新申请)

下载acme.sh curl https://get.acme.sh | sh -s emailmyexample.comcd ~/.acme.sh/获取Cloudflare密钥 Preferences | Cloudflare 登录选择账户详情选择API Token选择创建令牌选择区域DNS模板&#xff0c;并设置编辑写入权限生成并复制令牌备用回到首页概览界面下部获取账号…...

【C语言】进阶——结构体+枚举+联合

①前言&#xff1a; 在之前【C语言】初阶——结构体 &#xff0c;简单介绍了结构体。而C语言中结构体的内容还有更深层次的内容。 一.结构体 结构体(struct)是由一系列具有相同类型或不同类型的数据项构成的数据集合&#xff0c;这些数据项称为结构体的成员。 1.结构体的声明 …...

Socket编程基础(1)

目录 预备知识 socket通信的本质 认识TCP协议和UDP协议 网络字节序 socket编程流程 socket编程时常见的函数 服务端绑定 整数IP和字符串IP 客户端套接字的创建和绑定 预备知识 理解源IP和目的IP 源IP指的是发送数据包的主机的IP地址&#xff0c;目的IP指的是接收数据包…...

无线通信——Mesh自组网的由来

阴差阳错找到了一个工作&#xff0c;是做无线通信的&#xff0c;因为无线设备采用Mesh&#xff0c;还没怎么接触过&#xff0c;网上搜索下发现Mesh的使用场景不多&#xff0c;大部分都是用在家里路由器上面。所以写了片关于Mesh网的文档。Mesh网可应用在无网络区域的地方&#…...

LRU、LFU 内存淘汰算法的设计与实现

1、背景介绍 LRU、LFU都是内存管理淘汰算法&#xff0c;内存管理是计算机技术中重要的一环&#xff0c;也是多数操作系统中必备的模块。应用场景&#xff1a;假设 给定你一定内存空间&#xff0c;需要你维护一些缓存数据&#xff0c;LRU、LFU就是在内存已经满了的情况下&#…...

常用工具使用

ubuntu 1.1 ubuntu与windows 互相复制问题 方法一、 打开虚拟机 &#xff0c;点击上方导航栏 ‘虚拟机’ 查看VMware Tools是否安装&#xff0c;安装即可 方法二、 apt-get autoremove open-vm-tools apt-get install open-vm-tools apt-get install open-vm-tools-desktop…...

HashMap源码解析_jdk1.8(一)

HashMap解析 HashMap源码解析_jdk1.8&#xff08;一&#xff09;哈希常用数据结构查找/插入/删除性能比较。哈希冲突 HashMap的数据结构HashMap相关变量size和capacity HashMap源码解析_jdk1.8&#xff08;一&#xff09; 哈希 Hash&#xff0c;一般翻译做“散列”&#xff0…...

Android最好用的日志打印库(自动追踪日志代码位置)

给大家推荐一个自己写的日志打印的库&#xff0c;我愿称之为最强日志打印库&#xff1a;BytUtilLog Byt是Big一统的缩写&#xff0c;大一统日志打印库&#xff0c;哈哈&#xff01;搞个笑&#xff0c;很早就写好了&#xff0c;但后面忙起来就忘了写一篇文章推一下它了&#xff…...