【图论】树剖(上):重链剖分

一、前置知识清单

  1. 深度优先搜索DFS 点我复习
  2. 图的存储 复习链接敬请期待
  3. 树状数组 点我复习

二、树剖简介

树剖(树链剖分),是一种把树划分成链的算法,该算法分为重链剖分和长链剖分。
本文仅讨论重链剖分,长链剖分目前本人还不会,所以不予展示。

三、模拟重链剖分

图6是一棵树,我们钦定1号结点为根。
图6
图6

若要对这棵树进行重链剖分,首先要求出它的DFN序。注意这里的DFN序与DFS序还是有一定区别的。 DFN序就是优先遍历每个结点重儿子的DFS序。
以上面的图6为例,我们先求出以每个结点为根的子树重量 s i z i siz_i sizi(即以每个结点为根的子树所包含的结点个数)。该树中 s i z i siz_i sizi 分别等于 5 5 5 2 2 2 1 1 1 4 4 4 1 1 1
对于每个非叶子结点,找到其 s i z i siz_i sizi 最大的儿子(即重儿子),记为 s o n i son_i soni。若有多个儿子的 s i z i siz_i sizi 相等,则 s o n i son_i soni 取任意一个儿子均可。该树中 s o n i son_i soni 分别等于 4 4 4 3 3 3 0 0 0 2 2 2 0 0 0
我们将每个重儿子和它的父亲连接,形成一条条重链。该树中有两条重链: 1 1 1 4 4 4 2 2 2 3 3 3 为一条重链, 5 5 5 自成一条重链。

四、代码实现重链剖分

感谢@xixisuper_提供树剖代码。由于本人一顿操作,代码变得又长又唐,请见谅。

#include<bits/stdc++.h>
using namespace std;
vector<int>e[114514];
int fa[114514],dep[114514],siz[114514],son[114514];
//fa[i]存储每个非根节点的父亲,dep[i]存储每个结点的深度 
void dfs(int u,int father){int lz;fa[u]=father;dep[u]=dep[father]+1;siz[u]=1;lz=e[u].size();for(int i=0;i<lz;i++){if(e[u][i]==father)continue;//避免回搜 dfs(e[u][i],u);//本人的十手笔记本电脑写了auto会编译错误 siz[u]+=siz[e[u][i]];if(siz[son[u]]<siz[e[u][i]]) son[u]=e[u][i];}
}//找重儿子 
int dfn[114514],nidfn[114514],top[114514],tot;
//dfn[i]存储DFN序(点到下标),nidfn[i]存储逆DFN序(下标到点),你只需要知道这两个东西很有用就行了 
//top[i]存储链顶 
void pf(int u,int father){int lz; dfn[u]=++tot; nidfn[tot]=u;if(son[u]){top[son[u]]=top[u];pf(son[u],u);//先遍历重儿子 }lz=e[u].size();for(int i=0;i<lz;i++){if(e[u][i]==father)continue;//避免回搜 if(e[u][i]==son[u])continue;//重儿子已经遍历过了 top[e[u][i]]=e[u][i];pf(e[u][i],u);}
}//剖分,求DFN序 
int lowbit(int x){return x&(-x);
}
struct st{//使用树状数组维护区间和 int c[114514];void add(int x,int y){for(int i=x;i<=y;i+=lowbit(i))c[i]+=y;//单点修改 return;}void add(int x,int y,int z){for(int i=x;i<=y;i++)add(i,z);//这里的区间修改貌似有点怪怪的,有什么可以优化的地方请私信我,备注142719158return; }int query(int x){int r=0;//前缀查询for(int i=x;i;i-=lowbit(i))r+=c[i];return r;}int query(int x,int y){return query(y)-query(x-1);//区间查询 }
}tr;
void update(int x,int y,int z){//将x与y之间唯一路径上的点点权加上zwhile(top[x]!=top[y]){if(dep[top[x]]>dep[top[y]]){tr.add(dfn[top[x]],dfn[x],z);//当两个结点不在同一条链上时,深度更大的结点向上跳 x=fa[top[x]];//向上跳到链顶的父亲 }else{tr.add(dfn[top[y]],dfn[y],z);y=fa[top[y]];//向上跳到链顶的父亲 }}if(dep[x]>dep[y])tr.add(dfn[y],dfn[x],z);else tr.add(dfn[x],dfn[y],z);return; 
}
int qry(int x,int y){//查询x与y之间唯一路径上的点点权之和 int r=0; while(top[x]!=top[y]){if(dep[top[x]]>dep[top[y]]){r+=tr.query(dfn[top[x]],dfn[x]);//当两个结点不在同一条链上时,深度更大的结点向上跳 x=fa[top[x]];//向上跳到链顶的父亲 }else{r+=tr.query(dfn[top[y]],dfn[y]);y=fa[top[y]];//向上跳到链顶的父亲 }}if(dep[x]>dep[y])r+=tr.query(dfn[y],dfn[x]);else r+=tr.query(dfn[x],dfn[y]);return r;
}
int main(){dfs(1,0);top[1]=1;pf(1,0);return 0;
}

如果博客有错误,或者发现了代码中的问题,请联系我,备注142719158,我会尽快修正!鲁A济南车!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1555418.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL联合索引、索引下推Demo

1.联合索引 测试SQL语句如下&#xff1a;表test中共有4个字段(id, a, b, c)&#xff0c;id为主键 drop table test;#建表 create table test(id bigint primary key auto_increment,a int,b int,c int )#表中插入数据 insert into test(a, b, c) values(1,2,3),(2,3,4),(4,5,…

算法修炼之路之滑动窗口

目录 一&#xff1a;滑动窗口的认识及模板 二&#xff1a;LeetcodeOJ练习 1.第一题 2.第二题 3.第三题 4.第四题 5.第五题 6.第六题 7.第七题 一&#xff1a;滑动窗口的认识及模板 这里先通过一道题来引出滑动窗口 LeetCode 209 长度最小的子数组 画图分析&…

aws(学习笔记第一课) AWS CLI,创建ec2 server以及drawio进行aws画图

aws(学习笔记第一课) 使用AWS CLI 学习内容&#xff1a; 使用AWS CLI配置密钥对创建ec2 server使用drawio&#xff08;vscode插件&#xff09;进行AWS的画图 1. 使用AWS CLI 注册AWS账号 AWS是通用的云计算平台&#xff0c;可以提供ec2&#xff0c;vpc&#xff0c;SNS以及clo…

使用 Python 遍历文件夹

要解决这个问题&#xff0c;使用 Python 的标准库可以很好地完成。我们要做的是遍历目录树&#xff0c;找到所有的 text 文件&#xff0c;读取内容&#xff0c;处理空行和空格&#xff0c;并将处理后的内容合并到一个新的文件中。 整体思路&#xff1a; 遍历子目录&#xff1…

2.3MyBatis——插件机制

2.3MyBatis——插件机制 1.基本用法2.原理探究2.1加载过程2.2执行过程2.2.1 插件的执行点2.2.2 SQL执行的几个阶段2.2.3 如何梳理出执行流程 插件机制是一款优秀框架不可或缺的组成部分&#xff0c;比如spring、dubbo&#xff0c;还有我们要聊的Mybatis等等。所谓插件&#xff…

vSAN02:容错、存储策略、文件服务、快照与备份、iSCSI

目录 vSAN容错条带化存储策略1. 创建新策略2. 应用存储策略 vSAN文件服务文件服务快照与备份 vSAN iSCSI目标服务 vSAN容错 FTT&#xff1a;Fault to Tolerance 允许故障数 故障域&#xff1a;每一台vSAN主机是一个故障域 - 假设3台超融合&#xff08;3计算1存储&#xff09;&…

力扣 简单 110.平衡二叉树

文章目录 题目介绍解法 题目介绍 解法 平衡二叉树:任意节点的左子树和右子树的高度之差的绝对值不超过 1 //利用递归方法自顶向下判断以每个节点为根节点的左右子树的最大深度是否大于1 class Solution {public boolean isBalanced(TreeNode root) {if(root null){return tr…

基于Java的GeoTools对Shapefile文件属性信息深度解析

目录 前言 一、Shapefile的属性列表信息 1、属性表格信息 2、属性表格包含的要素 二、GeoTools对属性表格的解析 1、常规解析方法 2、基于dbf文件的属性信息读取 三、总结 前言 ESRI Shapefile&#xff08;shp&#xff09;&#xff0c;或简称shapefile&#xff0c;是美…

【Spring Boot React】Spring Boot和React教程 完整版

【Spring Boot & React】Spring Boot和React教程 在B站找到一个不错的SpringBoot和React的学习视频&#xff0c;作者是amigoscode 【Spring Boot & React】Spring Boot和React教程 2023年更新版【Spring Boot React】价值79.9美元&#xff0c;全栈开发&#xff0c;搭…

如何使用CMD命令启动应用程序(二)

说明&#xff1a;去年1024发布了一篇博客&#xff0c;介绍如何使用CMD命令启动应用程序&#xff0c;但实际情况&#xff0c;有些程序可能无法用配置环境变量的方式来启动&#xff0c;本文针对两种情况下的程序&#xff0c;如何使用CMD命令来启动&#xff0c;算是对上一篇博客的…

Qt操作主/从视图及XML——实例:汽车管理系统

目录 1. 主界面布局2.连接数据库3.主/从视图应用 1. 主界面布局 先创建一个QMainwindow&#xff0c;不带设计界面 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QGroupBox> #include <QTableView> #include <QListWidg…

鸿蒙harmonyos next flutter混合开发之开发plugin(获取操作系统版本号)

创建Plugin为my_plugin flutter create --org com.example --templateplugin --platformsandroid,ios,ohos my_plugin 创建Application为my_application flutter create --org com.example my_application flutter_application引用flutter_plugin&#xff0c;在pubspec.yam…

如何解决 MySQL ERROR 1040 (08004): Too many connections ?

MySQL 是最流行的开源关系数据库管理系统之一&#xff0c;它也是开发人员中非常常用的数据库。即便它高度健壮和可伸缩性极强&#xff0c;像任何软件一样&#xff0c;它也可能出现错误。我们会经常遇到一个错误&#xff0c;特别是在高流量系统中&#xff0c;error 1040 (08004)…

51c视觉~CV~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/11668984 一、 CV确定对象的方向 介绍如何使用OpenCV确定对象的方向(即旋转角度&#xff0c;以度为单位)。 先决条件 安装Python3.7或者更高版本。可以参考下文链接&#xff1a; https://automaticaddison.com/how-to-s…

阳台山足球营地的停车位探寻

阳台山足球营地的环境是真好哈。停车场名称&#xff1a;阳台山森林公园配套停车场。应该很多爬山的人车子也停在这里。而且我没想到的&#xff0c;阳台山的山泉水还有不少居民每天提着空桶去山上装。看来环境是真的很好哈 停车场有地面和地下停车场&#xff0c;停车位个数查不…

java 数据存储方式

1. 变量存储 这是最基本的数据存储方式&#xff0c;通过声明变量来存储数据。变量可以是基本数据类型&#xff08;如int、float、char等&#xff09;&#xff0c;也可以是引用数据类型&#xff08;如对象、数组等&#xff09;。变量存储的数据通常存储在内存中&#xff0c;随着…

【记录】Excel|Excel 打印成 PDF 页数太多怎么办

【记录】Excel&#xff5c;解决 Excel 打印成 PDF 页数过多的问题 文章目录 【记录】Excel&#xff5c;解决 Excel 打印成 PDF 页数过多的问题方法一&#xff1a;调整页边距WPS OfficeMicrosoft Excel 方法二&#xff1a;优化页面布局调整列宽和行高使用“页面布局”视图合并单…

python全栈开发是什么?

全栈指掌握多种技能&#xff0c;并能利用多种技能独立完成产品。通俗的说就是与这项技能有关的都会&#xff0c;都能独立完成。 python&#xff0c;因为目前很火&#xff0c;能开发的项目很多。例如&#xff1a;web前端后端&#xff0c;自动化运维&#xff0c;软件、小型游戏开…

八大排序--01冒泡排序

假设有一组数据 arr[]{2&#xff0c;0&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;7} 方法&#xff1a;开辟两个指针&#xff0c;指向如图&#xff0c;前后两两进行比较&#xff0c;大数据向后冒泡传递&#xff0c;小数据换到前面。 一次冒泡后&#xff0c;数组中最大…

【网络篇】计算机网络——应用层详述(笔记)

目录 一、应用层协议原理 1. 进入应用层 2. 网络应用程序体系结构 &#xff08;1&#xff09;客户-服务器体系结构&#xff08;client-server architecture&#xff09; &#xff08;2&#xff09; P2P 体系结构&#xff08;P2P architecture&#xff09; 3. 进程间通讯 …