dfs序

Posted liukx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dfs序相关的知识,希望对你有一定的参考价值。

dfs序

void dfs(int u,int fa)
{
    dfs_[++len]=u;  
    int sz=g[u].size();
    for(int i=0;i<sz;i++)
        if(g[u][i]!=fa)
            dfs(g[u][i],u);
}

所以对于一棵树的dfs序来说,这个点和他所有的子节点会被存储在连续的区间之中。

时间戳也很好理解,它就好比一个标签,贴在每一个点上,记录dfs第一次开始访问这个点的时间以及最后结束访问的时间。

所以如果一个点的起始时间和终结时间被另一个点包括,这个点肯定是另一个点的子节点。(算导里称之为括号化定理)

因此可以判断一个点是否是另一个点的子节点。

欧拉序

dfs到加进,dfs回加进,总共加入度遍。

void dfs(int u,int fa)
{
    a[++len]=u;
    int sz=g[u].size();
    for(int i=0; i<sz; i++)
    {
        if(g[u][i]!=fa)
        {
            dfs(g[u][i],u);
            a[++len]=u;
        }
    }
}

欧拉序的用处

1、求LCA

我们要求的两个点在欧拉序中的第一个位置之间肯定包含他们的lca,因为欧拉序上任意两点之间肯定包含从第一个点走到第二个点访问的路径上的所有点

所以只需要记录他们的深度,然后从两个询问子节点x,y第一次出现的位置之间的深度最小值即可

bfs序

1.在BFS序中,与点a相邻的下一个点可能有三种身份:(1)节点a的孩子 (2)节点a的第一后兄弟 (3)节点a的兄弟的孩子

2.在DFS序中,与点a相邻的下一个点可能有三种身份:(1)节点a的孩子(2)节点a的第一后兄弟(3)啥也不是(意思是说直接回到父辈及以上了)

q.push(1);
while (!q.empty()){
    int x=q.front();
    q.pop();
    for (int i=0;i<g[x].size();i++) {
        int y=g[x][i];
        if (y==fa[x]) continue;
        q.push(y);
    }
}

以上是关于dfs序的主要内容,如果未能解决你的问题,请参考以下文章

#144. DFS 序 1

codevs1228 (dfs序+线段树)

Leetcode102. 二叉树的层序遍历(经典dfs)

DFS 序 1 (Loj#144)

CodeForces 375D Tree and Queries 莫队||DFS序

[POI2007]MEG-Megalopolis (树状数组,Dfs序)