首页 > 其他分享 >prufer序列

prufer序列

时间:2024-02-21 14:56:50浏览次数:26  
标签:度数 结点 int fa 序列 prufer

prufer序列是一种树形结构和数列相互映射的规则

与其他序列的区别

dfs序,将一棵子树映射为一段连续的区间
二叉搜索树,中序遍历是单调不减的序列
prufer序列:

  • 1.是一个和树的双射,唯一对应一棵树
  • 2.包含结点的度数和连接关系

使用场景

将构造树转化为构造序列,将统计树转化为统计序列,将树的dp转化为数列的dp

如何得到prufer序列

  • 1.统计树上所有结点的度数degree[i]
  • 2.找到所有度数为1的结点中编号最小的那个结点cur
  • 3.令p[i]=fa[cur],同时将degree[fa[cur]]--
  • 4.重复步骤2-3,直到剩余两个点时结束

性质

  • 1.结点x在prufer序列中出现的次数+1就是degree[x]
  • 2.编号最大的点n绝对是剩下的2个结点之一

因此一般把n当作根节点,这样不会删掉根节点

P6086 【模板】Prufer 序列

#include<bits/stdc++.h>
#define int long long
using namespace std;
int pre[5000010];
int fa[5000010];
int deg[5000010];
int n,m;
int ans;

void prufer(){
	int cur;//fa为父亲序列 
	for(int i=1;i<=n;i++){
		if(deg[i]==1){
			cur=i;//最小的度数为1的点 
			break;
		}
	}
	int leaf=cur;
	for(int i=1;i<=n-2;i++){
		//cout<<leaf<<endl;
		ans=ans^(i*fa[leaf]);
		deg[fa[leaf]]--;
		if(deg[fa[leaf]]==1 && fa[leaf]<cur){
			leaf=fa[leaf];
			continue;
		}
		else{
			cur++;
			while(deg[cur]!=1){
				cur++;
			}
			leaf=cur;
		}
	}
	cout<<ans;
}

void pre_tree(){
	for(int i=1;i<=n;i++) deg[i]=1;
	int cur,leaf;
	for(int i=1;i<=n-2;i++) deg[pre[i]]++;
	for(int i=1;i<=n;i++){
		if(deg[i]==1){
			cur=i;
			break;
		}
	}
	leaf=cur;
	for(int i=1;i<=n-2;i++){
		int f=fa[leaf]=pre[i];
		deg[f]--;
		if(deg[f]==1 && f<cur){
			leaf=f;
			continue;
		}
		else{
			cur++;
			while(deg[cur]!=1){
				cur++;
			}
			leaf=cur;
		}
	}
	fa[leaf]=n;
	for(int i=1;i<n;i++) ans=ans^(fa[i]*i);
	cout<<ans;
}

signed main(){
	cin>>n>>m;
	if(m==1){
		for(int i=1;i<n;i++){
			cin>>fa[i];
			deg[i]++;
			deg[fa[i]]++;
		}
		//for(int i=1;i<=n;i++) cout<<deg[i]<<endl;
		prufer();
	}
	else{
		for(int i=1;i<n-1;i++){
			cin>>pre[i];
		}
		pre_tree();
	}	
	return 0;
}

P5454 [THUPC2018] 城市地铁规划

观察题目的便利度计算公式,发现这个东西显然是可以预处理的,而f(x)的参数x显然是点x的度数。

题目中说:
新建的地铁轨道尽可能少,但任意两座地标之间都需要能通过地铁相互到达。
其实就是一棵树,那么度数总和就是2n-2,于是可以对于度数完全背包(注意每一个点都必须有度数),并且在做完全背包的过程中记录上一个状态,以便得到每一个点的度数。

得到度数用prufer构造成树就行了(其他复杂度更高的方法也是可以的,瓶颈在完全背包);

标签:度数,结点,int,fa,序列,prufer
From: https://www.cnblogs.com/wangwenhan/p/18025188

相关文章

  • 深度学习在时间序列预测的总结和未来方向分析
    2023年是大语言模型和稳定扩散的一年,时间序列领域虽然没有那么大的成就,但是却有缓慢而稳定的进展。Neurips、ICML和AAAI等会议都有transformer结构(BasisFormer、Crossformer、Invertedtransformer和Patchtransformer)的改进,还出现了将数值时间序列数据与文本和图像合成的新体......
  • R语言k-Shape时间序列聚类方法对股票价格时间序列聚类|附代码数据
    原文链接:http://tecdat.cn/?p=3726最近我们被客户要求撰写关于时间序列聚类的研究报告,包括一些图形和统计输出。本文我们将使用k-Shape时间序列聚类方法检查与我们有业务关系的公司的股票收益率的时间序列企业对企业交易和股票价格在本研究中,我们将研究具有交易关系的公司的......
  • Pandas处理时间序列数据
    Pandas时序处理中最常见的两种数据类型为datetime和timedelta。flowchartTBdatetime--data-->2024-01-01datetime--time-->10:00:00datetime顾名思义就是既有日期date也有时间time,表示一个具体的时间点(时间戳)。timedelta则表示两个时间点之间的差,比如2024-0......
  • 代码随想录 day56 最长递增子序列 最长连续递增序列 最长重复子数组
    最长递增子序列dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度状态转移方程的含义:位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列+1的最大值。最长连续递增序列dp[i]:以下标i为结尾的连续递增的子序列长度为dp[i]。如果nums[i]>nums[i-1......
  • python实战:使用json序列化
    一,官方文档:https://docs.python.org/zh-cn/3/library/json.html二,json与字典的相互转化1,字典转json字符串1234567importjson #字典转jsond=dict(name='Tom',age=2,score=88)json_d=json.dumps(d)print(type(json_d))print(json_d)......
  • P2023 [AHOI2009] 维护序列
    原题链接code#definelllonglong#include<bits/stdc++.h>usingnamespacestd;lltree[410000]={0};llwait_mul[410000]={0};llwait_add[410000]={0};lln,p;inlinevoidread(ll&x){x=0;llflag=1;charc=getchar();while(c......
  • rust结构体包含另一个结构体引用时,serde序列化问题
    代码如下useserde::{Deserialize,Serialize};#[derive(Serialize,Deserialize)]structPerson{id:String,name:String,}#[derive(Serialize,Deserialize)]structMsg<'a>{id:String,person:&'aPerson,}fnmain(){......
  • DP19 最长公共子序列(一)C
    建议直接网上看思路....#include<stdio.h>intmax(inti,intj){if(i>j)returni;returnj;}intmaxlength[1001][1001];intmain(){intn,m;while(scanf("%d%d",&n,&m)!=EOF){charc=getchar();//读取换行char......
  • KY78 最大上升子序列和C++
    这个解决问题的思路使用动态规划,即用已知状态去得到未知状态。思路逻辑是这样sum[i]记录以A[i]为末上升子序列的和的最大值然后从j从0-i-1遍历如果A[j]<A[i]那么sum[i]=sum[j]+A[i];然后找出sum[i]中的的最大值,就是以A[i]为末上升子序列的和的最大值。这样就实现了从前......
  • day29 回溯算法part5 代码随想录算法训练营 491. 非递减子序列
    题目:491.非递减子序列我的感悟:难不怕,不行就抄一遍,再默写一遍,多记忆几遍。加油!!!理解难点:uset是本层的, res收获的是节点(满足要求的节点),不用return(用了return是仅仅收集叶子节点的)判断的逻辑,是nums[i]当前的节点和目标的path的区别代码示例:classSolution:......