zoukankan      html  css  js  c++  java
  • dfs序介绍

    来自  :http://www.cnblogs.com/zhouzhendong/p/7264132.html#undefined

    Dfs序是一棵树从根节点出发,dfs遍历时依次经过的节点序列。

     

    如上图的dfs序为:

    1,2,3,6,4,5,7

    或者

    1,4,5,7,2,3,6

    或者

    1,4,2,6,3,5,7

    ……

    总之可以有很多种,具体看输入时的建边顺序或者处理方式等因素。

    不同的dfs序一般不会影响解题正确性和效率。

    性质

    对于一棵树的dfs序而言,同一棵子树所对应的一定是dfs序中连续的一段。

    这个性质非常重要,在利用dfs序来解题的过程中,这个不可缺少!

     

    证明: 在dfs遍历时,当进入一个节点之后,dfs会先把当前的节点的所有子节点都遍历一遍,然后在回溯到当前节点,在这个过程中,它的所有子孙节点一定都被访问过了,而且在这之前,它的任何一个子孙节点都不可能被访问过。然后它才离开当前子树,回到父亲节点,再访问其他子树,所以同一子树的节点在dfs序中一定是连续的一段。

    不妨可以看着下面的这棵树来试试~

     

    实现

    Dfs,顺便记录下访问的顺序。比如设dfn[x]为第x个访问的节点。

    那么怎么获取当前节点在dfs序中的范围呢?

    稍微具体一点的过程:我们只要设一个时间 time,一开始是0,每遍历到一个新的节点就+1。那么,当前节点的访问时间范围就是当前节点的访问标号范围。设in[x]为进入当前节点时的时间,out[x]为离开当前节点时的时间,那么子树x在dfs序里所对应的范围就是in[x]~out[x]。

    但是,我们在具体操作的过程中,往往不记录dfs序,因为重要的往往是范围。注意,in[x]是第一次访问节点x的时间,in[x]≠dfn[x],而dfn[in[x]]=x。

    用途

    dfs序的主要作用就是将一个子树变成序列上的一个连续区间。

    类似于“修改某某节点,询问包含节点到根路径的最大/最小/sum”等的一系列“长”在树上的像线段树一样的问题很多都能够通过dfs序得到解决。

    例题

    HDU5692 Snacks  题解

    给定一棵n个点的有根树,每个点有一个点权。根节点为0,节点标号为0~n-1。

    定义最大路径为:从根出发走到某个点,点权和最大的路径。

    现在有Q次操作,每种是以下两种之一:

    (1).将点x的点权变成v。

    (2).求经过某一个点的最大路径的点权和。

    POJ3321 Apple Tree  题解写好了,有兴趣可以去这里逛逛~

    给定一棵n个点的有根苹果树,每个点上最多只有一个苹果,现在有Q次操作:

    (1).修改一个点上的苹果个数。

    (2).求某个子树内有几个苹果。

    n,Q<=10^5.

  • 相关阅读:
    P3531 [POI2012]LIT-Letters
    CF1338B Edge Weight Assignment
    CF118C Fancy Number
    New Year Contest
    P2587 [ZJOI2008]泡泡堂
    2021拓维游记
    CF1338C Perfect Triples
    gcc、g++、gdb安装
    vim教程之背键盘使我快乐
    Python起个头
  • 原文地址:https://www.cnblogs.com/wjhstudy/p/9827216.html
Copyright © 2011-2022 走看看