ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

模板:Prufer序列

2022-02-07 18:57:59  阅读:137  来源: 互联网

标签:度数 int fa 序列 du Prufer 模板


所谓 Prufer 序列,就是 Prufer 发明的序列。

(逃)

前言

优雅的神奇魔术。
看名字很高大难,但实际上是高大清(小清新)。
很简单的建立起树与序列之间的双射,且这个序列的性质非常良好,且这个序列的性质与度数密切相关。
能优雅简洁的证明一些恶心的结论。

解析

定义

把一棵树转化为 Prufer 序列的流程如下:

  1. 找到当前度数为1且编号最小的点 x x x。
  2. 将 x x x 点删去,将唯一与 x x x 相连的点 f f f (可以理解为以n作根情况下的“父亲”)加入 Prufer 序列。
  3. 将 f f f 的度数减一。
  4. 不断执行 1-3,直到只剩下两个点。

最终我们得到的长度为 n − 2 n-2 n−2 的序列即最终的 Prufer 序列。

性质

其有如下性质:

  1. 序列中的每个数都是 [ 1 , n ] [1,n] [1,n] 之间。
  2. 一个度数为 d x d_x dx​ 的点在序列中出现 d x − 1 d_x-1 dx​−1 次。
  3. 最终剩下的两个点中必然有一个点为 n n n。

都较为显然。

把树转化为 Prufer 序列

利用 Prufer 序列的定义,开一个堆存当前的度数为1的点,即可 O ( n log ⁡ n ) O(n\log n) O(nlogn) 的构造。
但可以做到线性。
维护一个指针 p p p,从1扫到n,表示当前编号最小的一度点。每次后移指针知道找到一个一度点,将其加入 Prufer 序列,如果父亲减完度数变成了一度点且编号小于 p p p 则将父亲加入序列,并递归的考虑祖父,否则直接忽略。
注意这么做最后会得到一个 n − 1 n-1 n−1 的序列,因为最后会把和 n n n 相连的点也删去。把序列尾抹掉即可。

for(int i=1;i<n;i++){
		fa[i]=read();
		du[i]++;du[fa[i]]++;
	}
	for(int p=1;p<n;p++){
		if(du[p]>1) continue;
		q[++tot]=fa[p];
		int f=fa[p];
		--du[f];
		while(du[f]==1&&f<p){
			q[++tot]=fa[f];
			f=fa[f];
			--du[f];
		}
	}
	--tot;

把 Prufer 序列转化为树

利用 Prufer 序列的性质2,我们可以得到每个点的度数。
每次找到最小的一度点,它的父亲就是当前序列的队首元素,将其与队首连边,队首的度数减一,并后移队首指针。
和树转化为 Prufer 序列类似的,我们也可以维护一个指针 p p p 做到线性。
注意,由于 Prufer 序列的长度只有 n-2,我们必然只为 n-2 个结点分配了“父亲”(即连了n-2条边),最后我们最后找到那个没有被分配父亲的非 n 的点,将其与 n 相连即可。

for(int i=1;i<=n;i++) du[i]=1;
	for(int i=1;i<=n-2;i++){
		q[i]=read();++du[q[i]];
	}
	int pl=1;
	for(int p=1;p<n&&pl<=n-2;p++){
		if(du[p]>1) continue;
		int x=p;
		while(x<=p&&du[x]==1&&pl<=n-2){
			fa[x]=q[pl];
			du[q[pl]]--;
			x=q[pl];
			++pl;
		}
	}
	for(int i=1;i<n;i++) if(!fa[i]) fa[i]=n;

凯莱定理

通过上面的构造我们可以知道,有标号无根树和Prufer序列是双射关系
Prufer 序列的个数显然为 n n − 2 n^{n-2} nn−2 个,那么我们也就自然得出了凯莱定理

n n n 个结点的有标号无根树有 n n − 2 n^{n-2} nn−2 个。

标签:度数,int,fa,序列,du,Prufer,模板
来源: https://blog.csdn.net/BUG_Creater_jie/article/details/122812925

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有