浅谈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. Java Web 学习(7) —— Spring MVC 之国际化

    Spring MVC 之国际化 i18n 与 l10n internationalization:国际化,以 i 开头,以 n 结尾,中间 18 个字母,简称 i18n. localization:本 ...

  2. bzoj 5218: [Lydsy2017省队十连测]友好城市

    题意: 这题显然直接tarjan是做不了的. 这里安利另一个求SCC的算法Kosaraju,学习的话可以见这篇博客 于是结合莫队,我们有了个暴力. 发现主要瓶颈是dfs过程中找最小的未经过的点,我们用 ...

  3. Python网络编程基础 struct模块 解决黏包问题 FTP

    struct模块 解决黏包问题 FTP

  4. Zotero入门精通

    一.Zotero简介 Zotero作为一款协助科研工作者收集.管理以及引用研究资源的免费软件,如今已被广泛使用.此篇使用说明主要分享引用研究资源功能,其中研究资源可以包括期刊.书籍等各类文献和网页.图 ...

  5. 详解JAVA8Stream 方法引用(基础){全}

    1: Stream流 1.1 引言 1.2 流式思想概述 1.3 获取流 1.4 常用方法 1.5 练习:集合元素处理 2:方法引用 2.1 冗余的Lambda场景 2.2 方法引用符 2.3 通过对 ...

  6. pytest框架之fixture前置和后置

    一.conftest.py 定义公共的fixture,多个测试类中都可以调用 pytest提供了conftest.py文件,可以将fixture定义在此文件中 运行测试用例时,不需要去导入这个文件,会 ...

  7. 使用vue组件需要注意的4个细节

    细节1:table(表格)中直接引用自定义组件出现的bug 如上图,tr本应在tbody中面,现在却是同级.造成的原因是h5规定table里必须有tbody,tbody中必须有tr, 当tbody中引 ...

  8. .net core使用NLog日志

    前言:NLog日志对.net core web项目最新的支持在官网上有最新的介绍: 官网介绍地址:https://github.com/NLog/NLog/wiki/Getting-started-w ...

  9. JS基础语法---分支语句之:三元表达式

    获取两个数字中的最大值 用if-else语句        var num1 = 10;        var num2 = 100;        if (num1 > num2) {     ...

  10. 用vue和layui简单写一个响应式数据展示表

    在创建项目之前,先把我们需要的文件打包处理 <!DOCTYPE html> <html lang="en"> <head> <meta c ...