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.

猜你喜欢

转载自www.cnblogs.com/wjhstudy/p/9827216.html
今日推荐