DFS序详解
来源:互联网 发布:知乎live可以搜索吗 编辑:程序博客网 时间:2024/04/27 17:29
http://cdnnn.07net01.com/2015/08/899785.html
http://blog.csdn.net/ccsu_001/article/details/47667587
这是我将上面的2篇博客合成的一篇文章,链接如上
给定一棵n个节点的树,m次查询,每次查询需要求出某个节点深度为h的所有子节点。
对于这个问题如果试图去对每个节点保存所有深度的子节点,在数据大的时候内存会吃不消;或者每次查询的时候去遍历一遍,当数据大的时候,时间效率会非常低。
此时如果使用dfs序维护树结构就可以轻松地解决这个问题。
作为预处理,首先将将树的所有节点按深度保存起来,每个深度的所有节点用一个线性结构保存,每个深度的节点相对顺序要和前序遍历一致。
然后从树的根节点进行dfs,对于每个节点记录两个信息,一个是dfs进入该节点的时间戳in[id],另一个是dfs离开该节点的时间戳out[id]。
最后对于每次查询,求节点v在深度h的所有子节点,只需将深度为h并且dfs进入时间戳在in[v]和out[v]之间的所有节点都求出来即可,由于对于每个深度的所有节点,相对顺序和前序遍历的顺序以致,那么他们的dfs进入时间戳也是递增的,于是可以通过二分搜索求解。
分析
Step 1:
如下图,可以看到,由于普通的树并不具有区间的性质,所以在考虑使用线段树作为解题思路时,需要对给给定的数据进行转化,首先对这棵树进行一次dfs遍历,记录dfs序下每个点访问起始时间与结束时间,记录起始时间是前序遍历,结束时间是后序遍历,同时对这课树进行重标号。
Step 2:
如下图,DFS之后,那么树的每个节点就具有了区间的性质。
那么此时,每个节点对应了一个区间,而且可以看到,每个节点对应的区间正好“管辖”了它子树所有节点的区间,那么对点或子树的操作就转化为了对区间的操作。
【PS: 如果对树的遍历看不懂的话,不妨待会对照代码一步一步调试,或者在纸上模拟过程~】
Step 3:
这个时候,每次对节点进行更新或者查询,就是线段树和树状数组最基本的实现了…
- DFS序详解
- dfs序详解
- 树 DFS序 详解[完全版]
- DFS序详解 Codeforces Round #442 E
- dfs.replication 详解
- DFS算法详解
- BFS 、DFS区别,详解
- 没事找事写算法(1)-------详解树链剖分及DFS序
- 深度优先搜索(DFS)详解
- 深度优先搜索(DFS)详解
- 数据结构----BFS和DFS详解
- c++:DFS与BFS详解
- DFS序
- dfs序
- dfs序
- dfs序
- dfs序
- dfs序
- Cc2540 协议栈UART实验
- C++ 在.h文件中包含头文件和在.cpp文件中包含头文件有什么区别?
- JAVA动态代理
- POJ Human Gene Functions 1080 lcs 变形 DP
- Android 判断摄像头权限方法
- DFS序详解
- Fragment的知识
- x265-1.7版本-encoder/slicetype.cpp注释
- UI_Button的应用
- 我的剪贴板
- Intent的初步了解
- ORACLE--COUNT()函数使用
- 网页设计基础
- 抓取远程图片到本地,小实例