dfs序和欧拉序构造方法及常用性质

背景:有个题解需要介绍下这两者的性质,这里就顺便写了个总结了
核心:将树上问题转化成区间问题

欧拉序

欧拉序,有2*n2*n-1个编号
dfs序,有n个编号

(2021年8月30日21点27分)upd:更新下面的第二种叫法为 欧拉环游序
欧拉序,我理解的有两种搞法(可能叫法有误,思想就是那个思想

  • 进入节点记录,遍历完所有子节点后,出节点时,当前时间戳记录
  • 进入节点记录,遍历子节点的时候,返回到本节点时记录

具体代码体现为
d f n [ x ] dfn[x] dfn[x] 记录的是, x x x节点的时间戳

s a [ y ] sa[y] sa[y]记录的是,时间戳为 y y y 的是哪个节点(也就是“谁”的意思)
第一种

void dfs(int u) {
	sa[++tim] = u;
	dfn[u] = tim;
	for (son...) dfs(son);
	
	sa[++tim] = u;
}

第二种

void dfs(int u) {
	sa[++tim] = u;
	dfn[u] = tim;
	for (son...) {
		dfs(son);
		sa[++tim] = u;
	}
}

这两者之间在处理树上问题时有不同的性质
例如有一棵树为

1 2
1 3
2 4
2 5
3 6
3 7
dfs序和欧拉序构造方法及常用性质_第1张图片

这里时间戳 d f n dfn dfn,指的是第一次进入节点的时间
第一种欧拉序可以为,2*N

欧拉序:1 2 4 4 5 5 2 3 6 6 7 7 3 1
时间戳:1 2 3 3 5 5 2 8 9 9 11 11 8 1

第二种为,2*N-1

欧拉序:1 2 4 2 5 2 1 3 6 3 7 3 1
时间戳:1 2 3 2 5 2 1 8 9 8 11 8 1

第一种的性质:

  • 树上任意一点 x x x 的子树,在第一次出现 x x x最后一个 x x x之间的所有出现的数,另外有个性质是这些出现次数和为偶数
    举例:2 的子树,截取为2 4 4 5 5 2中的4 4 5 5,自行尝试一下其它的子树
  • 树上任意两点 x x x y y y,路径上的点,为最后一个 x x x第一个 y y y之间,出现奇数次的数。另外再加上lca(最近公共祖先)
    举例:47 的树上路径
    截取为4 5 5 2 3 6 6 7,出现奇数次的数字4 2 3 7,加上lca,树上路径的节点最终为4 2 1 3 7
  • 通常将树上的问题,转化为区间问题求解,比如树上莫队,求解树链上不同数字的个数等等

第二种的性质:

  • 树上任意一点的子树为,第一次出现 x x x最后一个 x x x之间出现了的所有数,除去本节点的数
    举例:2的子树,截取为2 4 2 5 2,除去本节点为4 5
  • 树上任意两点 x x x y y y,两点的 l c a lca lca,为第一次出现 x x x第一次出现 y y y区间内,时间戳最小的那个值
    举例:47lca,截取为4 2 5 2 1 3 6 3 7,注意,这里的时间戳,指的是第一次进入节点的时间
    按照截取的数字,给出时间戳为
    3 2 5 2 1 8 9 8 11,时间戳最小的为1时刻,那么去找1时刻的那个点是谁,也就是欧拉序第1个位置的那个点,lca就是节点1
  • 通常用作求 lca,结合ST表,在 O ( 1 ) O(1) O(1)时间内求解 l c a lca lca,适合在频繁求解 l c a lca lca的场景

dfs序

仅进入节点的时候记录
代码体现为

void dfs(int u) {
	sa[++tim] = u;
	dfn[u] = tim;
	for (son...) dfs(son);
}

d f s序:1 2 4 5 3 6 7
时间戳:1 2 3 4 5 6 7

性质:

  • 树上任意点 x x x 的子树(包含 x x x)为,当前第一次出现 x x x的位置到往后 s z [ x ] sz[x] sz[x] 个节点的区间, s z [ x ] sz[x] sz[x]表示 d f s dfs dfs 时计算的 以 x x x为根 的树大小,假设 s z [ x ] sz[x] sz[x]包含了 x x x
    举例:
    2 2 2 的子树, s z [ 2 ] = 3 sz[2]=3 sz[2]=3
    那么截取为,2 4 5,如果要不包含 x x x,取 x x x往后,区间大小为 s z [ x ] − 1 sz[x]-1 sz[x]1即可,也就是4 5
  • 树上两点 x x x y y y l c a lca lca,需要配合链剖分,将树链变成一块块连续的序列,跳 t o p top top求解,这里不细说,但是却是比较重要常用的一部分,详细可以找找树链剖分的板子题康康
  • 通常结合树剖等等进行维护树上链上的信息,比如,给某条链全部节点加上1,求解最大最小值等等

你可能感兴趣的:(图论,树形结构,数据结构)