树链剖分,顾名思义就是将树形的结构剖分成链,我们以此便于在链上操作

首先我们需要明白在树链剖分中的一些概念

重儿子:某节点所有儿子中子树最多的儿子

重链:有重儿子构成的链

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操作的更多相关文章

  1. 浅谈树链剖分 F&Q

    这是一篇迟来的博客,由于我懒得写文章,本篇以两个问题阐述笔者对树链剖分的初步理解. Q1:树链剖分解决什么问题? 树链剖分,就是把一棵树剖分成若干连续的链,将这些链里的数据映射在线性数组上维护.比方说 ...

  2. 浅谈树链剖分(C++、算法、树结构)

    关于数链剖分我在网上看到的有几个比较好的讲解,本篇主要是对AC代码的注释(感谢各位witer的提供) 这是讲解 http://www.cnblogs.com/kuangbin/archive/2013 ...

  3. 树链剖分求LCA

    树链剖分中各种数组的作用: siz[]数组,用来保存以x为根的子树节点个数 top[]数组,用来保存当前节点的所在链的顶端节点 son[]数组,用来保存重儿子 dep[]数组,用来保存当前节点的深度 ...

  4. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  5. HDU 3966 (树链剖分+线段树)

    Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...

  6. hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...

  7. Qtree3题解(树链剖分(伪)+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意: 很明显吧.. 题解: 我的做法十分的暴力:树链剖分(伪)+线段树+\(set\)... ...

  8. Qtree3题解(树链剖分+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意 很易懂吧.. 题解 我的做法十分的暴力:树链剖分(伪)+线段树+ std :: set ...

  9. 树链剖分&dfs序

    树上问题 很多处理区间的问题(像是RMQ,区间修改).可以用线段树,树状数组,ST表这些数据结构来维护.但是如果将这些问题挪到了树上,就不能直接用这些数据结构来处理了.这时就用到了dfs序和树链剖分. ...

随机推荐

  1. [MySQL] mysql 的读写锁与并发控制

    1.无论何时只要有多个查询在同一时刻修改数据,都会产生并发控制的问题 2.讨论mysql在两个层面,服务器层和存储引擎层,如何并发控制读写 3.举了个mbox邮箱文件的例子,说如果有多个进程同时对mb ...

  2. PHP中利用pcntl实现多进程(模拟多线程)实例(转)

    windows不支持pcntl的多线程(非Unix类系统不支持此模块),pcntl在很久很久之前就听过了,但是一直没有尝试着真正要用它. 这不,遇到socket问题了,看socket,遇到pcntl了 ...

  3. python学习笔记(六)、类

    Python与java.c++等都被视为一种面向对象的语言.通过创建自定义类,用于处理各种业务逻辑.面向对象有封装.继承.多态三个特征,这也是面子对象语言的通用特征. 1 封装 封装,是值向外部隐藏内 ...

  4. Linux基础(Ubuntu16.04):安装vim及配置

    1.进入终端  Ctrl + Alt +T 出现终端窗口 2.输入命令: sudo apt-get install vim-gtk 3.验证是否成功 安装完vim后查看命令 vi tab键,就会关联出 ...

  5. 微信小程序域名配置问题

    最主要的:不能用ip地址,不能用localhost,域名要经过备案等 这些在 https://developers.weixin.qq.com/miniprogram/dev/framework/ab ...

  6. vue2.x 给一个对象里添加一个没有的属性

    obj = {...obj, name:'addName'} //给obj对象 添加一个name字段,并且赋值为‘addName’ 参考:

  7. Chrome opacity非1时border-radius圆角边框剪裁问题

    border-radius:50%可以让元素正方形元素表现为正圆. 如果元素设置了border边框,则会表现为一个正圆圈圈,类似这样: 但有时候,border边框的这个圈圈会在边缘处发生剪裁,个别浏览 ...

  8. (最完美)小米平板3的USB调试模式在哪里开启的流程

    经常我们使用安卓手机链上电脑的时候,或者使用的有些应用软件比如我们公司营销小组经常使用的应用软件引号精灵,之前的老版本就需要开启usb调试模式下使用,现经常新版本不需要了,如果手机没有开启usb调试模 ...

  9. SQL SERVER 执行动态SQL EXEC

    :普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_executesql N's ...

  10. MFC界面相关源码

    这是这4篇MFC界面的相关源码.建议学习Visual C++的看看这2本微软官方出的教材. [MFC Windows程序设计(第2版,修订版)](美)Jeff Prosise著 [Windows程序设 ...