码迷,mamicode.com
首页 > 其他好文 > 详细

dfs序

时间:2020-07-06 18:11:54      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:标签   最小值   另一个   时间   continue   ++   意思   因此   直接   

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序

标签:标签   最小值   另一个   时间   continue   ++   意思   因此   直接   

原文地址:https://www.cnblogs.com/liukx/p/13255901.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!