• dfs序和欧拉序


    study from:

    https://www.cnblogs.com/stxy-ferryman/p/7741970.html

    如果侵权,请提醒我。

    1.dfs序

    l/r:该点作为根节点的子树中,节点的最小编号/最大编号(初进入,最后离开的当前编号)。其中初进入的编号,可认为是该节点的编号。

    l~r:记录了该点作为根节点的子树的所有节点

    可以判断一个点是否在另外一个点作为根节点的子树上

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <time.h>
     6 #include <string>
     7 #include <set>
     8 #include <map>
     9 #include <list>
    10 #include <stack>
    11 #include <queue>
    12 #include <vector>
    13 #include <bitset>
    14 #include <ext/rope>
    15 #include <algorithm>
    16 #include <iostream>
    17 using namespace std;
    18 #define ll long long
    19 #define minv 1e-6
    20 #define inf 1e9
    21 #define pi 3.1415926536
    22 #define E  2.7182818284
    23 const ll mod=1e9+7;//998244353
    24 const int maxn=1e5+10;
    25 
    26 int l[maxn]={0},r[maxn]={0},ti=0,tl[maxn],tr[maxn];
    27 
    28 void dfs(int d)
    29 {
    30     ti++;
    31     tl[d]=ti;
    32     if (l[d]!=0)
    33         dfs(l[d]);
    34     if (r[d]!=0)
    35         dfs(r[d]);
    36     tr[d]=ti;
    37 }
    38 
    39 int main()
    40 {
    41     int n,root,x,y,z,i;
    42     scanf("%d%d",&n,&root);
    43     for (i=1;i<n;i++)
    44     {
    45         scanf("%d%d%d",&x,&y,&z);
    46         if (z==0)
    47             l[x]=y;
    48         else
    49             r[x]=y;
    50     }
    51     dfs(root);
    52     for (i=1;i<=n;i++)
    53         printf("%d %d
    ",tl[i],tr[i]);
    54     return 0;
    55 }
    56 /*
    57 8 1
    58 1 2 0
    59 1 3 1
    60 2 4 0
    61 2 5 1
    62 3 6 1
    63 5 7 0
    64 6 8 0
    65 */

    例题:

    http://acm.hdu.edu.cn/showproblem.php?pid=3887

    对于每个节点,它的子树上标号比它小的点有多少个(by 其它博客)

    求子树权值和+树状数组

      1 //用node而不释放内存会出现MLE;也许这里使用vector方便一点
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <cstring>
      6 #include <time.h>
      7 #include <string>
      8 #include <set>
      9 #include <map>
     10 #include <list>
     11 #include <stack>
     12 #include <queue>
     13 #include <vector>
     14 #include <bitset>
     15 #include <ext/rope>
     16 #include <algorithm>
     17 #include <iostream>
     18 using namespace std;
     19 #define ll long long
     20 #define minv 1e-6
     21 #define inf 1e9
     22 #define pi 3.1415926536
     23 #define E  2.7182818284
     24 const ll mod=1e9+7;//998244353
     25 const int maxn=1e5+10;
     26 
     27 struct node
     28 {
     29     int d;
     30     node *next;
     31 }*e[maxn];
     32 
     33 int f[maxn],v[maxn]={0},n;
     34 bool vis[maxn];
     35 
     36 void dfs(int d)
     37 {
     38     int j;
     39     node* p=e[d];
     40     vis[d]=1;
     41 
     42     j=d-1;
     43     while (j>0)
     44     {
     45         v[d]-=f[j];
     46         j-=(j & (-j));
     47     }
     48 
     49     while (p)
     50     {
     51         if (!vis[p->d])
     52             dfs(p->d);
     53         p=p->next;
     54     }
     55 
     56     j=d-1;
     57     while (j>0)
     58     {
     59         v[d]+=f[j];
     60         j-=(j & (-j));
     61     }
     62 
     63     j=d;
     64     while (j<=n)
     65     {
     66         f[j]++;
     67         j+=(j & (-j));
     68     }
     69 }
     70 
     71 int main()
     72 {
     73     node *p,*pp;
     74     int i,x,y,root;
     75     while (1)
     76     {
     77         memset(v,0,sizeof(v));
     78         memset(f,0,sizeof(f));
     79         memset(vis,0,sizeof(vis));
     80         scanf("%d%d",&n,&root);
     81         for (i=1;i<=n;i++)
     82             e[i]=NULL;
     83         if (n==0)
     84             break;
     85         for (i=1;i<n;i++)
     86         {
     87             scanf("%d%d",&x,&y);
     88             p=(node*) malloc (sizeof(node));
     89             p->d=y;
     90             p->next=e[x];
     91             e[x]=p;
     92 
     93             p=(node*) malloc (sizeof(node));
     94             p->d=x;
     95             p->next=e[y];
     96             e[y]=p;
     97         }
     98         dfs(root);
     99         for (i=1;i<=n;i++)
    100         {
    101             printf("%d",v[i]);
    102             if (i!=n)
    103                 printf(" ");
    104             else
    105                 printf("
    ");
    106         }
    107         for (i=1;i<=n;i++)
    108         {
    109             p=e[i];
    110             while (p)
    111             {
    112                 pp=p;
    113                 p=p->next;
    114                 free(pp);
    115             }
    116         }
    117     }
    118     return 0;
    119 }

    2.欧拉序

    遍历的编号。回溯时的点也要记录在内。

     

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <time.h>
     6 #include <string>
     7 #include <set>
     8 #include <map>
     9 #include <list>
    10 #include <stack>
    11 #include <queue>
    12 #include <vector>
    13 #include <bitset>
    14 #include <ext/rope>
    15 #include <algorithm>
    16 #include <iostream>
    17 using namespace std;
    18 #define ll long long
    19 #define minv 1e-6
    20 #define inf 1e9
    21 #define pi 3.1415926536
    22 #define E  2.7182818284
    23 const ll mod=1e9+7;//998244353
    24 const int maxn=1e5+10;
    25 
    26 int l[maxn]={0},r[maxn]={0},ti=0,tl[maxn],tr[maxn];
    27 
    28 void dfs(int d)
    29 {
    30     ti++;
    31     printf("%d ",d);
    32     if (l[d]!=0)
    33     {
    34         dfs(l[d]);
    35         ti++;
    36         printf("%d ",d);
    37     }
    38     if (r[d]!=0)
    39     {
    40         dfs(r[d]);
    41         ti++;
    42         printf("%d ",d);
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     int n,root,x,y,z,i;
    49     scanf("%d%d",&n,&root);
    50     for (i=1;i<n;i++)
    51     {
    52         scanf("%d%d%d",&x,&y,&z);
    53         if (z==0)
    54             l[x]=y;
    55         else
    56             r[x]=y;
    57     }
    58     dfs(root);
    59     return 0;
    60 }
    61 /*
    62 8 1
    63 1 2 0
    64 1 3 1
    65 2 4 0
    66 2 5 1
    67 3 6 1
    68 5 7 0
    69 6 8 0
    70 */

    例题:

    1.

    lca 模板题

    https://www.luogu.org/problemnew/show/P3379

    2.

    给你一棵树,告诉你每个点的点权,给你m个x和w,表示将子树x中每个点的权值和加w,然后再给你t个x,表示询问x子树中所有点的权值之和.

    from https://www.cnblogs.com/stxy-ferryman/p/7741970.html

    !子树,一个范围[x,y],用线段树

    若最后询问,用标记

  • 相关阅读:
    二、Redis服务启动以及请求流程
    三、Redis数据结构动态字符串SDS(simple dynamic string)
    java中Math类的常用API
    MySQL 8.0安装教程
    ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'%'
    记录一些壁纸/图片网站
    LeetCode No32. 最长有效括号
    LeetCode No35. 搜索插入位置
    LeetCode No942. 增减字符串匹配
    LeetCode Weekly Contest 292
  • 原文地址:https://www.cnblogs.com/cmyg/p/9544279.html
Copyright © 2020-2023  润新知