dfs序

Posted mltang

tags:

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

 惊了,从别人那里偷了一个dfs序。世界真神奇

 dfs序什么意思呢,就是对dfs走过的地方进行标序,每个节点建立一个

 struct node{

  int in,out;

  .........

 };

 这个in就是你什么时候进入这个节点,out就是什么时候从这个节点出来,程序也很好实现,加个计数cnt就行了,遍历一遍,

{ in = ++cnt;

  dfs(。。。。);

  out = cnt;   }

  大致就是这个样子

  

 

  那么dfs序有什么用呢,脑补一下,每个节点我都做成了一个区间,并包括他所有的子区间(子节点)

  一般用线段树管理,时间复杂度就下来了

 

  再说一下为什么时间复杂度会下来,因为用到    dfs序+线段树    这种题一般都是多个修改,多个查询,点还特别多,

  问题一般还是问你某个节点后面有多少个含有某种属性的节点(比如说每个节点都有一种颜色,他问你后面的节点中红色有多少个)

  不用这个的话每次查询就是遍历后面的所有点,基本一次查询就是n(一共n个节点)的复杂度,m次查询就是O(m*n),基本都是超时

  

  

  线段树查询 logn,一下子时间就降下来了

 

            1

         2     3

       4         5  6

  用dfs排完序那么就是   1是(1,6)    2是(2,3)   3是(4,6)   4是(3,3)   5是(5,5)   6是(6,6)   

  现在用线段树构造   

      (1,6)                           (1,6)

    (2,3)   (4,6)                   (1,3)              (4,6)

   (3,3)  (5,5)     (6,6)             (1,2)      (3,3)     (4,5)     (6,6) 

                                  (1,1)   (2,2)        (4,4)   (5,5)

 

  左边的(1,6)是第一个点      它的值等于右边的(1,1)

 

代码:

#include <iostream>

#include <vector>

using namespace std;

const int N = 1e5 + 5;

int cnt = 0,in[N],out[N],pre[N],arr[N];

vector<int> pp[N];

//pp[i]装的是i后面紧连着的字节点

void dfs(int n)

{

    for(int i = 0;i < pp[n].size(); ++i)

    {

        int d = pp[n][i];

        in[d] = ++cnt;

        pre[cnt] = d;//pre存储的是in值对应的点

        dfs(d);

        out[d] = cnt;

    }

}

int main()

{

    in[1] = 1;

    out[1] = n;

}

  

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

dfs序和欧拉序

DFS序

DFS序 + 板子

dfs序

dfs序

DFS序详解