dfs 序 欧拉序
推荐博客 :https://www.cnblogs.com/stxy-ferryman/p/7741970.html
DFS序其实就是一棵树顺次访问的结点的顺序,例如下面这棵树
它的 dfs 序就是 A-B-D-E-G-C-F-H
int key = 0;
void dfs(int x, int fa){
dfs_[cnt++] = x;
s[x] = ++key;
for(int i = 0 ; i < ve[x].size(); i++){
int to = ve[x][i];
if (to == fa) continue;
dfs(to, x);
}
//dfs_[cnt++] = x;
e[x] = key;
}
我们这里的 dfs_[ ] 数组表示的就是这棵树的 dfs 序,s[ ] 与 e[ ] 数组表示的就是访问某个结点的时间顺序。
借助 dfs序,我们可以将树的结点变成一维的数组的形式,观察上面的图,B的子树中的结点有DEG,其在 dfs序中也是连续的。因此可以通过时间戳很容易找到子树的开始时间和结束时间。
可以发现作为子树的时间戳一定在其内部。
通过这个dfs序我们还可以做很多事情,比如给你一颗 n 个结点的树,m 个操作,每次操作可以使某一棵子树全部加上或减去某一个值,问最后每个点的值是多少, 或某个子树的权值之和是多少?
看到这里再想这个问题就很简单了,找到dfs序,利用差分,就可以实现 o(1)的修改了。
二 、 欧拉序
欧拉序,就是从根节点出发,按照dfs顺序在绕回到根节点,其有两种不同的写法
( 1 )
int cnt = 1;
void dfs(int x, int fa){
dfs_[cnt++] = x;
for(int i = 0 ; i < ve[x].size(); i++){
int to = ve[x][i];
if (to == fa) continue;
dfs(to, x);
dfs_[cnt++] = x;
}
}
(2)
int cnt = 1;
void dfs(int x, int fa){
dfs_[cnt++] = x;
for(int i = 0 ; i < ve[x].size(); i++){
int to = ve[x][i];
if (to == fa) continue;
dfs(to, x);
}
dfs_[cnt++] = x;
}
这两种是比较常见的欧拉序的写法。
那么欧拉序有什么用呢?
还是上面提到的问题,我们会发现所有的字母都出现了两次,相同的两个字母之间表示以其为根的所有子树,注意这些点都是出现两次的。计算的时候同样是将差分的数组累加,最后除以2即可。
dfs 序 欧拉序的更多相关文章
- 树的遍历顺序 - dfs序|欧拉序|dfn序(备忘)
(仅作备忘) dfs序是dfs过程中对于某节点进入这个节点的子树和离开子树的顺序 满足每个节点都会在dfs序上出现恰好两次 任意子树的dfs序都是连续的 欧拉序是dfs过程中经过节点的顺序 每个节点至 ...
- 树的dfs序.欧拉序
dfs序 ==先序,连续一段区间就是子树
- dfs序和欧拉序
生命不息,学习不止,昨天学了两个算法,总结一下,然而只是略懂,请路过的大佬多多谅解. 一.dfs序 1.什么是dfs序? 其实完全可以从字面意义上理解,dfs序就是指一棵树被dfs时所经过的节点的 ...
- lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增
https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...
- 图论——Tarjan 初步 DFS序+时间戳+欧拉序
一.什么是DFS序: DFS序是按照先序遍历,先遍历根节点然后依次遍历左子树,右子树的过程,每次遇到新的节点就把新访问节点加到序列中,代码如下: int DFSrk[100000]; int cnt= ...
- LCA-RMQ+欧拉序
还是那一道洛谷的板子题来说吧 传送门 其实好几天之前就写了 结果dr实在是太弱了 没有那么多的精力 于是就一直咕咕咕了 哎 今天终于补上来了 LCA概念传送门 RMQ传送门 这个算法是基于RMQ和欧拉 ...
- Underground Lab CodeForces - 782E (欧拉序)
大意:$n$结点,$m$条边无向图, 有$k$个人, 每个人最多走$\left\lceil\frac {2n}{k}\right\rceil$步, 求一种方案使得$k$个人走遍所有的点 $n$结点树的 ...
- Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)
题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...
- 【BZOJ 3772】精神污染 主席树+欧拉序
这道题的内存…………………真·精神污染……….. 这道题的思路很明了,我们就是要找每一个路径包含了多少其他路径那么就是找,有多少路径的左右端点都在这条路径上,对于每一条路径,我们随便选定一个端点作为第 ...
随机推荐
- LCA (最近公共祖先)倍增做法 —— O(nlogn)预处理 O(logn)(在线)查询
pa[a][j] 表示 a 结点的 2^j倍祖先(j = 0时 为直接父亲,j = 1时为父亲的父亲……) 1.首先预处理出所有结点的深度值dep和父亲结点 void dfs(int u, int f ...
- 【7003】&&【a203】合并多项式
Time Limit: 3 second Memory Limit: 2 MB 问题描述 求两个一元多项式的和.输入多项式方式为:多项式项数.每项系数和指数,按指数从大到小的顺序输入.输出多 ...
- Linux 内核 回顾: ISA
设计上 ISA 总线非常老了, 并且是非常地低能, 但是它仍然持有一块挺大的控制设备的 市场. 如果速度不重要并且你想支持老式主板, 一个 ISA 实现要优于 PCI. 这个老标准 的另外一个好处是如 ...
- ffmpeg 转码并截图的命令分析
一.转码并截图的命令分析: 1.转码并截图,将码率转换为900Kffmpeg -i E:\\1.MOV -i E:\\123.jpg -filter_complex overlay=W-w -b:v ...
- C++ 动态加载 DLL 时,GetProcAddress() 返回 NULL,GetLastError() 获取错误代码为 127
1.问题现象: 采用“运行期间动态链接”自己的 dll 文件,LoadLibrary() 成功获取 dll 模块句柄,但是 GetProcAddress() 返回 NULL. 2.问题分析: 调用 G ...
- .net webapi 文件夹上传
如果我是DJ,是DJ,是DJ,是DJ,是DJ,是DJ,是DJ,是DJ,是DJ,是DJ,,, 前言 文件夹上传目前仅支持chrome内核的浏览器. 后期整理到git(2019-5-23说:不整理了,我要 ...
- 【译】PEP 318--函数和方法的装饰器
PEP原文 : https://www.python.org/dev/peps/pep-0318 PEP标题: Decorators for Functions and Methods PEP作者: ...
- Oracle 11g静默安装
1.检查安装包 安装依赖包 yum -y install gcc make binutils gcc-c++ compat-libstdc++-33 elfutils-libelf-devel elf ...
- mysql主从之基于gtid的主从复制
一 GITD介绍 1.1 gtid的含义 Global Transaction Identifier,全局事务标识 阿里云的rds目前已经使用gtid 基于gtid的主从复制原理 每个mysql数据库 ...
- 洛谷$P1155$ 双栈排序 贪心+二分图匹配
正解:贪心+二分图匹配 解题报告: 传送门$QwQ$ 跪了,,,我本来以为我$NOIp$做得差不多了,,,然后康了一眼发现没做多少啊其实$QAQ$ 然后来康题趴$QwQ$ 首先考虑如果只有一个栈的情况 ...