【学习笔记】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 n−2的prufer序列的个数,自然为 n n − 2 n^{n-2} nn−2, C a y l e y Cayley Cayley定理得证
Prufer序列的性质
由Prufer序列构造的过程,我们可以发现其具有两个显而易见的性质。
-
构造完后剩下的两个节点里,一定有一个是编号最大的节点。
-
对于一个 n 度的节点,其必定在序列中出现 n−1 次。因为每次删去其子节点它都会出现一次,最后一次则是删除其本身。一次都未出现的是原树的叶子节点。
应用
1、无向完全图的不同生成树数:
n n − 2 n^{n−2} nn−2 。
2、 n 个点的无根树计数:
同上问题。
3、 n 个点的有根树计数:
对每棵无根树来说,每个点都可能是根,故总数为 n n − 2 × n = n n − 1 n^{n−2}×n=n^{n−1} nn−2×n=nn−1 。
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=1ndi−1(n−2)!
5、 有标号的完全二分图 K n , m K_{n,m} Kn,m的生成树个数为 n m − 1 m n − 1 n^{m-1}m^{n-1} nm−1mn−1:
考虑将其生成树的prufer序列按照原本顺序分成 f i ≤ n , f i > n f_i\leq n,f_i>n fi≤n,fi>n两部分。
对于 f i ≤ n f_i\leq n fi≤n的部分,一定是删去某个标号 > n >n >n的点之后留下 f i f_i fi的,因为这是一张二分图。所以该部分的点一定恰好有 m − 1 m-1 m−1个(右部有m个点,整张图删完之后一定在左右部各留下一个点,所以右部一共要删去 m − 1 m-1 m−1个点)
f i > n f_i>n fi>n部分同理。
所以此时还是可以用一个prufer序列与合法生成树对应,故方案数为 n m − 1 m n − 1 n^{m-1}m^{n-1} nm−1mn−1
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(k−1n−1)fn−kmk+(k−1n−1)gkhn−k
其中 m i m_i mi表示大小为 i i i的有标号无根树的个数, g i g_i gi表示大小为 i i i的所有有标号无根树的权值和, h n − k h_{n-k} hn−k表示大小为 n − k n-k n−k的森林的数量。 ( n − 1 k − 1 ) \binom{n-1}{k-1} (k−1n−1)是因为枚举的k的含义是n所在树的大小,我要从剩下 n − 1 n-1 n−1个点里面选 k − 1 k-1 k−1个点。如果不这样枚举的树的组合就会算重。
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=nn−2
对于 g n g_n gn,我们枚举所有度数为i的贡献
转化到prufer序列中看这个问题,度数为i,表示出现了 i − 1 i-1 i−1次,所以强制选定对应的数字以及位置,剩下的 n − 1 n-1 n−1个数随便放
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=1n−1i2n(i−1n−2)n−1n−1−i
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(i−1n−1)hn−imi
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} (d1−1,d2−1...dk−1k−2)
对于每一个连通块,固定连边的标号顺序(比如第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} (d1−1,d2−1...dk−1k−2)∗∏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=k−2(d1,d2...dkk−2)∗∏i=1kaidi+1=∑∑di=k−2∏i=1kdi!(k−2)!∗∏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!}) =(k−2)!∏i=1kai(∑∑i=1kdi=k−2∏i=1kdi!aidi)
注意到 ( k − 2 ) ! ∏ i = 1 k a i (k-2)!\prod_{i=1}^{k} a_i (k−2)!∏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)!} [xk−2]∏i=1keaix=[xk−2]enx=(k−2)!nk−2
所以最终答案为 n k − 2 ∏ i = 1 k a i n^{k-2}\prod_{i=1}^{k}a_i nk−2∏i=1kai
相关文章:
【学习笔记】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: ①从树上选择编号最小的叶子节点&#x…...
由于找不到msvcr110.dll的5种解决方法
在使用电脑的过程中,我们可能会遇到一些问题,比如打开软件时提示找不到 msvcr110.dll 文件丢失。这通常意味着该文件已被删除或损坏,导致程序无法正常运行。本文将介绍几种解决方案,帮助您解决这个问题。 首先,我们需…...
最长连续递增子序列
给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。 输入格式: 输入第1行给出正整数n(≤105);第2行给出n个整数,…...
Java学习星球,十月集训,五大赛道(文末送书)
目录 什么是知识星球?我的知识星球能为你提供什么?专属专栏《Java基础教程系列》内容概览:《Java高并发编程实战》、《MySQL 基础教程系列》内容概览:《微服务》、《Redis中间件》、《Dubbo高手之路》、《华为OD机试》内容概览&am…...
前端VUE---JS实现数据的模糊搜索
实现背景 因为后端实现人员列表返回,每次返回的数据量在100以内,要求前端自己进行模糊搜索 页面实现 因为是实时更新数据的,就不需要搜索和重置按钮了 代码 HTML <el-dialogtitle"团队人员详情":visible.sync"centerDi…...
Android Studio 的android.jar文件在哪儿
一般在:C:\Users\admin\AppData\Local\Android\Sdk\platforms\android-33下(不一定是33,这个得看你Android Studio->app->builde.gradle的targetSdk是多少) 怎么找: 1.打开Android Studio 粘贴地址后࿰…...
Elasticsearch 部署学习
文章目录 Elasticsearch 部署学习1. 单节点部署 elasticsearch1.1 部署 jdk1.2 下载 elasticsearch1.3 上传文件并修改配置文件1.4 启动1.5 问题总结1.6 浏览器验证 2. 集群部署 elasticsearch3. 常用命令4. Elasticsearch kibana安装:one: 参考部署文档:two: 下载对应版本的安…...
nodejs 如何在npm发布自己的包 <记录>
一、包结构 必要结构: 一个包对应一个文件夹(文件夹名不是包名,但最好与包名保持一致,包名以package.json中的name为主)包的入口文件index.js包的配置文件package.json包的说明文档README.md 二、需要说明的文件 1.配…...
移植RTOS的大体思路
最首先当然是去官网看看是不是已经支持目标芯片啦,没有的话,就需要自己手动移植了 获取源码 一般可以从rtos官网或者GitHub上获取源码 确认源码结构 这种有官方文档说明,需要修改的一般都是BSP和libcpu相关文件夹中的内容 CPU架构移植 …...
FPGA到底是什么?
首先只是凭自己浅略的了解,FPGA好像也是涉及到了开发板,单片机之类的东西,和嵌入式十分相似,但是比嵌入式更高级的东西。 肯定有很多小伙伴如我一样,只是听说过FPGA,听别人说的传呼其神,那么它到…...
算法-单词搜索 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,拼接后的单词如果在答案集中&…...
怒刷LeetCode的第15天(Java版)
目录 第一题 题目来源 题目内容 解决方法 方法一:哈希表双向链表 方法二:TreeMap 方法三:双哈希表 第二题 题目来源 题目内容 解决方法 方法一:二分查找 方法二:线性搜索 方法三:Arrays类的b…...
Android开发MVP架构记录
Android开发MVP架构记录 安卓的MVP(Model-View-Presenter)架构是一种常见的软件设计模式,用于帮助开发者组织和分离应用程序的不同组成部分。MVP架构的目标是将应用程序的业务逻辑(Presenter)、用户界面(V…...
day2作业
1,输入两个数,完成两个数的加减乘除 #输入两个数,完成两个数的加减乘除 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. 删除有序数组中的重复项 - 力扣(LeetCode) 题目: 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 …...
基于C#的AE二次开发之IQueryFilter接口、ISpatialFilter接口、IQueryDef 接口的查询接口的介绍
一、开发环境 开发环境为ArcGIS Engine 10.2与Visual studio2010。在使用ArcEngine查询进行查询的时候主要使用三种查询接口IQueryFilter(属性查询) 、ISpatialFilter(空间查询) 、IQueryDef (多表查询) 那…...
Oracle 11g RAC部署笔记
搭了三次才搭好,要记录一下。 1. Oracle 11g RAC部署的相关步骤以及需要的包,可以参考这里。 Oracle 11g RAC部署_12006142的技术博客_51CTO博客Oracle 11g RAC部署,Oracle11gRAC部署操作环境: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,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意:最终,合并…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
