蒟蒻浅谈树链剖分之一——两个dfs操作
树链剖分,顾名思义就是将树形的结构剖分成链,我们以此便于在链上操作
首先我们需要明白在树链剖分中的一些概念
重儿子:某节点所有儿子中子树最多的儿子
重链:有重儿子构成的链
dfs序:按重儿子优先遍历时的顺序
轻儿子的意思就与重儿子相反
首先是第一个dfs操作
在本次操作中,我们主要做的是处理所有节点的父亲,子树大小,重儿子,深度等操作
void dfs1(int now,int father,int deep)
{
tree[now].depth=deep;//初始化当前节点的深度,子树大小,父亲
tree[now].size=;
tree[now].fa=father;
maxson=-;
for(int i=head[now];i;i=tree[i].next)
{
int v=tree[now].to;
if(v==tree[now].father)//因为练的是双向边,所以不免会练到自己的父亲节点,就跳过
{
continue;
}
dfs(v,now,deep+);
tree[now].size+=tree[v].size;//累加子树的大小
if(tree[v].size>maxson)
{
tree[now].son=v;
maxson=size[v];
}
}
}
接下来就是第二次dfs操作,将树剖分成链的过程
我们在这时就有一个非常重要的东西那就是dfs序
dfs序就是我们遍历时的顺序,在这里的遍历方式是二叉树的中序遍历
因为我们在树链剖分中是以重儿子优先
所以dfs序可能会与实际有出入
所以我们还需新开一个数组来维护新的dfs序
以便于我们的线段树操作
但蒟蒻太弱,以后再来讲套线段树的事情
我们先好好的剖分吧
void dfs2(int now,int topf)//从当前节点开始,topf为当前链的顶端
{
tree[now].index=++TIME;//dfs序
w[tree[now].index]=tree[now].value;//维护
tree[now].top=topf;//初始化,链顶即为topf
if(!tree[now].son)//没有重儿子就先不用便利了
{
return;
}
dfs(tree[now].son,topf);//优先遍历重儿子
for(int i=head[now];i;i=tree[i].next)//在处理其他的情况
{
int v=tree[i].to;
if(v==father||v==tree[now].son)//不能为自己的父亲节点,也不能为重儿子
{
continue;
}
dfs(v,v);//在轻儿子那里新开一条链
}
}
所以说两个dfs还是比较好理解的
关键的是在树链剖分里更好的套数据结构
欲知后事如何,请听下回分解!
蒟蒻浅谈树链剖分之一——两个dfs操作的更多相关文章
- 浅谈树链剖分 F&Q
这是一篇迟来的博客,由于我懒得写文章,本篇以两个问题阐述笔者对树链剖分的初步理解. Q1:树链剖分解决什么问题? 树链剖分,就是把一棵树剖分成若干连续的链,将这些链里的数据映射在线性数组上维护.比方说 ...
- 浅谈树链剖分(C++、算法、树结构)
关于数链剖分我在网上看到的有几个比较好的讲解,本篇主要是对AC代码的注释(感谢各位witer的提供) 这是讲解 http://www.cnblogs.com/kuangbin/archive/2013 ...
- 树链剖分求LCA
树链剖分中各种数组的作用: siz[]数组,用来保存以x为根的子树节点个数 top[]数组,用来保存当前节点的所在链的顶端节点 son[]数组,用来保存重儿子 dep[]数组,用来保存当前节点的深度 ...
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- HDU 3966 (树链剖分+线段树)
Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...
- hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...
- Qtree3题解(树链剖分(伪)+线段树+set)
外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意: 很明显吧.. 题解: 我的做法十分的暴力:树链剖分(伪)+线段树+\(set\)... ...
- Qtree3题解(树链剖分+线段树+set)
外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意 很易懂吧.. 题解 我的做法十分的暴力:树链剖分(伪)+线段树+ std :: set ...
- 树链剖分&dfs序
树上问题 很多处理区间的问题(像是RMQ,区间修改).可以用线段树,树状数组,ST表这些数据结构来维护.但是如果将这些问题挪到了树上,就不能直接用这些数据结构来处理了.这时就用到了dfs序和树链剖分. ...
随机推荐
- js事件冒泡机制
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- C++ 浅拷贝与深拷贝探究
C++浅拷贝与深拷贝探究 浅拷贝与深拷贝的概念是在类的复制/拷贝构造函数中出现的. 拷贝构造函数使用场景 对象作为参数,以值传递方式传入函数(要调用拷贝构造函数将实参拷贝给函数栈中的形参) 对象作为返 ...
- java基础知识总结一:
四种内部类 直接抛出异常 单例模式: 懒汉式单例.饿汉式单例.登记式单例 []关于内部类: []关于异常: 直接捕捉并抛出异常:不需要给异常添加名字: if(i>10)throw ...
- SQL Server 数据库部分常用语句小结(一)
1. 查询某存储过程的访问情况 SELECT TOP 1000 db_name(d.database_id) as DBName, s.name as 存储名字, s.type_desc as 存储类 ...
- 【原】Java学习笔记012 - 数组
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:小店对自己的 ...
- Type '' cannot conform to protocol '' because it has requirements that cannot be satisfied
我有一个Objective-C协议,我试图在Swift类中实现.例如: @class AnObjcClass; @protocol ObjcProtocol <NSObject> - (v ...
- 【重新发布,代码开源】FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片
原创博客,转载请注明出处:[重新发布,代码开源]FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片 - 没落骑士 - 博客园 https://www.cnblogs.com/m ...
- frameset基础了解
frameset 元素可定义一个框架集.它被用来组织多个窗口(框架). 列子:一个分为头部导航栏.左边目录.右侧主体信息.(暂时没设计底部栏) <frameset rows="100, ...
- SpringBoot使用注解实现事务管理
conttoller controller和普通的controller类一样, 不用改变 @RequestMapping(value = "/path/{id}", method ...
- Linux Collection:软件配置
PAS Debian 9安装最新版Firefox( Firefox 58+/Quantum) Debian 9(Strech)的仓库包含的是firefox-esr(52)版本:需要安装最新版,有如下两 ...