浅谈DFS序

本篇随笔简要讲解一下信息学奥林匹克竞赛中有关树的DFS序的相关内容。

DFS序的概念

先来上张图:

树的DFS序,简单来讲就是对树从根开始进行深搜,按搜到的时间顺序把所有节点打上时间戳。

就比如上面这棵树,它的一个DFS序就是:

1 2 8 8 5 5 2 7 7 4 3 9 9 3 6 6 4 1

注意两点:

首先,一棵树的DFS序不唯一。因为深搜的时候选择哪个子节点的顺序是不一样的。

其次,对于一棵树进行DFS序,需要把回溯的时候的节点编号也记录一下,这就是为什么每个数字在DFS序中会出现两遍的原因。


求DFS序的代码实现

代码实现很简单,就是从根节点开始深搜,然后按顺序打标记就可以了。

在下面的代码中,\(id[]\)数组就是DFS序的数组,\(cnt\)就是计时变量,上传参数的\(f\)表示当前节点\(x\)的父亲。

void dfs(int x,int f)
{
id[x]=++cnt;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==f)
continue;
dfs(y,x);
}
}

DFS序的性质

观察上图:

和这棵树的一个DFS序:

1 2 8 8 5 5 2 7 7 4 3 9 9 3 6 6 4 1

我们发现,一个数字两次出现的位置所夹的区间,正好是以这个数为根的一个子树。比如:

2 8 8 5 5 2

就表示以2为根的子树是:2 8 5

我们发现:DFS序的一个性质就是把一棵子树放在一个区间里。这个优秀的性质把树状结构变成了线性结构。方便我们进行统计。


DFS序的部分应用

刚刚提到的DFS序的性质让DFS序列成为了描述树的一种方式。准确地来说,DFS序让我们把树状结构变成了一个线性的结构。我们只需要在这个线性结构上进行区间修改、区间查询,而不需要再一遍遍地遍历整个子树来做到修改和查询。

这种性质的最显然应用就是在树链剖分中。树链剖分就是把树拆成一条条轻重链来把树的所有点映射到一棵线段树上来进行树上的修改与统计。它的实现原理就是DFS序。

如果有兴趣学习树链剖分的读者,请移步这篇博客:

树链剖分详解

树上的很多问题都可以用到DFS序,这里不再一一列举。希望读者能掌握:树转区间的这个性质。在以后的OI生涯中加以应用。

浅谈DFS序的更多相关文章

  1. 浅谈DFS,BFS,IDFS,A*等算法

    搜索是编程的基础,是必须掌握的技能.--王主任 搜索分为盲目搜索和启发搜索 下面列举OI常用的盲目搜索: 1.dijkstra 2.SPFA 3.bfs 4.dfs 5.双向bfs 6.迭代加深搜索( ...

  2. 浅谈dfs

    搜索(dfs) 搜索分为bfs与dfs 他们的算法思路都是相同的--穷举 可以说,搜索是万能的,但是复杂度往往是指数级的,往往是穷途末路才用的最后方案 dfs dfs核心操作:回溯+前进 想想你第一次 ...

  3. 蒟蒻浅谈树链剖分之一——两个dfs操作

    树链剖分,顾名思义就是将树形的结构剖分成链,我们以此便于在链上操作 首先我们需要明白在树链剖分中的一些概念 重儿子:某节点所有儿子中子树最多的儿子 重链:有重儿子构成的链 dfs序:按重儿子优先遍历时 ...

  4. 莫队浅谈&题目讲解

    莫队浅谈&题目讲解 一.莫队的思想以及莫队的前置知识 莫队是一种离线的算法,他的实现借用了分块的思想.在学习莫队之前,本人建议学习一下分块,并对其有一定的理解. 二.莫队 现给出一道例题:bz ...

  5. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  6. .net中对象序列化技术浅谈

    .net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储 ...

  7. javascript数组浅谈2

    上次说了数组元素的增删,的这次说说数组的一些操作方法 join()方法: ,,] arr.join("_") //1_2_3 join方法会返回一个由数组中每个值的字符串形式拼接而 ...

  8. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  9. 浅谈sql 、linq、lambda 查询语句的区别

    浅谈sql .linq.lambda 查询语句的区别 LINQ的书写格式如下: from 临时变量 in 集合对象或数据库对象 where 条件表达式 [order by条件] select 临时变量 ...

随机推荐

  1. 0day2安全——笔记1

    第一章 PE和内存之间的映射 节偏移 文件偏移地址(File Offset Address):数据在PE文件中的地址 装载地址(Image Base):PE装入内存的基地址 虚拟内存地址(Virtua ...

  2. acwing 70-72 剑指OFFER 二叉树相关

    地址 https://www.acwing.com/problem/content/66/ https://www.acwing.com/problem/content/67/ https://www ...

  3. layUI学习第三日:layUI模块化开发

    layui 定义为「经典模块化」,具备早前 AMD 的影子,又并非受限于 CommonJS 的那些条条框框, BootStrap 的不同在于:layui 糅合了自身对经典模块化的理解. 除了 layu ...

  4. awk命令使用整理

    1. awk默认以空格分隔, 可摘出指定位置的内容, 通常用法如下( 文件名称为file.txt ): 文件中行内容为:  12:3   a  4:56   b awk  '{print $1}'  ...

  5. console调试技巧

    1.console.log() 我们经常会使用console.log来打印出某个变量的值或者某个实体对象,也可以传入多个变量参数,它会按照传入顺序进行打印: 1. 传入一个变量 const a = 1 ...

  6. [学习笔记] Manacher与PAM

    \(1\) Manacher 挺短,背是挺好背的 Manacher用于求回文串长度.思想大概就是: 1.加入字符集之外的识别字符(比如#)分隔开原来相邻的字母,这样所有的回文串都变成了以某个字符为中心 ...

  7. .NET Core NuGet 多项目套餐打包的正确姿势

    NuGet 默认只支持一个菜一个菜打包,不支持套餐打包.当对一个 csproj 项目进行 nuget 打包时(比如使用 dotnet pack 命令),只会将当前项目 build 出来的 dll 程序 ...

  8. SQL Server查询某个表被哪些存储过程调用

    问题描述: 今天有个同事问到如何查询某个表被哪些存储过程调用, 然后同事说可以用SQL search查询,自己试了一下确实可以 sqlsearch下载说明地址:https://www.cnblogs. ...

  9. copy_from/to_user详解

    参考:http://www.wowotech.net/memory_management/454.html 宋大侠的文章精彩,郭大侠的评论也精彩. 结论简单摘录如下: 无论是内核态还是用户态访问合法的 ...

  10. 登录注册案例(Servlet+JSP+Maven)

    项目案例模板之登录注册的实现 案例演示 案例代码 设计表 pom.xml  <dependencies>  <dependency>    <groupId>jun ...