zoukankan      html  css  js  c++  java
  • 祖孙询问 (lca或dfs序+时间戳)

    问题 F: 祖孙询问

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 13  解决: 6  难度:提高+/省选-
    [提交] [状态] [讨论版] [命题人:xcgzjia]

    题目描述

    输入

    输出

    样例输入 Copy

    10
    234 -1
    12 234
    13 234
    14 234
    15 234
    16 234
    17 234
    18 234
    19 234
    233 19
    5
    234 233
    233 12
    233 13
    233 15
    233 19

    样例输出 Copy

    1
    0
    0
    0
    2

    提示

     

     
     思路:
      方法1
      很明显是一道求lca的题
      求出lca判断就可以了
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int mssc=4e4+5;
     4 int n,m;
     5 int d[mssc],f[mssc][20];
     6 vector<int> g[mssc];
     7 void pre(int u,int fa){//初始化 
     8     d[u]=d[fa]+1;//求深度 
     9     for(int i=1;i<=15;i++){//i的范围根据题的数据范围而定 
    10         f[u][i]=f[f[u][i-1]][i-1];
    11     }
    12     int sz=g[u].size();//表示u所连接的边数 
    13     for(int i=0;i<sz;i++){
    14         if(g[u][i]!=fa){//g[u][i]表示以u为起点所连接的第i条边的终点 
    15             f[g[u][i]][0]=u;
    16             pre(g[u][i],u);
    17         }
    18     }
    19 }
    20 int lca(int x,int y){
    21     if(d[x]<d[y]){//让x为深度最深的点 
    22         swap(x,y);
    23     }
    24     for(int i=15;i>=0;i--){//跳到同一深度 
    25         if(d[f[x][i]]>=d[y]){
    26             x=f[x][i];
    27         }
    28         if(x==y){//如果此时是同一个点就输出 
    29             return x;
    30         }
    31     }
    32     for(int i=15;i>=0;i--){//让x,y同时向上跳 
    33         if(d[f[x][i]]!=d[f[y][i]]){//如果不是同一点就更新x,y的值 
    34             x=f[x][i];             //如果是同一点那么x的父节点就是答案 
    35             y=f[y][i];
    36         }
    37     }
    38     return f[x][0];//答案就是x的父节点 
    39 }
    40 int main(){
    41     scanf("%d",&n);
    42     int root;
    43     int a,b;
    44     for(int i=1;i<=n;i++){
    45         scanf("%d%d",&a,&b);
    46         if(b==-1){
    47             root=a;
    48         }else{
    49             g[a].push_back(b);
    50             g[b].push_back(a);    
    51         }
    52     }
    53     pre(root,0);
    54     scanf("%d",&m);
    55     for(int i=1;i<=m;i++){
    56         scanf("%d%d",&a,&b);
    57          int t=lca(a,b);
    58         if(t==a&&b!=t){
    59             printf("%d
    ",1);        
    60         }else if(t==b&&a!=t){
    61             printf("%d
    ",2);
    62         }else{
    63             printf("%d
    ",0);
    64         }
    65     }
    66     return 0;
    67 }
     方法2
      求出给定树的dfs序
      观察可以发现,如果存在x,y有祖孙关系,那么无非就有两种情况:
      第一种是x在y的区间内
      第二种就是y在x的区间内
      那么我们只要求出x和y进入dfs的时间和离开的时间查看他们的包含情况就可以了
      也就是说 求出这棵树所有点dfs序的时间戳 问询的时候判断一下即可
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=400005;
     4 int len,n,m,tim;
     5 int st[maxn],et[maxn];
     6 int pos[maxn];
     7 vector<int> g[maxn];
     8 void dfs(int u,int fa){
     9     st[++len]=++tim;
    10     pos[u]=len;
    11     int sz=g[u].size();
    12     for(int i=0;i<sz;i++){
    13         if(g[u][i]!=fa){
    14             dfs(g[u][i],u);
    15         }
    16     }
    17     et[pos[u]]=++tim;
    18 }
    19 int main(){
    20     scanf("%d",&n);
    21     int a,b,root;
    22     for(int i=1;i<=n;i++){
    23         scanf("%d%d",&a,&b);
    24         if(b==-1){
    25             root=a;
    26         }else{
    27             g[a].push_back(b);
    28             g[b].push_back(a);
    29         }
    30     }
    31     dfs(root,0);
    32     scanf("%d",&m);
    33     for(int i=1;i<=m;i++){
    34         scanf("%d%d",&a,&b);
    35         a=pos[a];
    36         b=pos[b];
    37         if(st[a]<st[b]&&st[b]<et[b]&&et[b]<et[a]){//a is elder
    38             printf("%d
    ",1);
    39         }else if(st[a]>st[b]&&st[a]<et[a]&&et[b]>et[a]){//b is elder
    40             printf("%d
    ",2);
    41         }else{
    42             printf("%d
    ",0);
    43         }
    44     }
    45     return 0;
    46 }
     
  • 相关阅读:
    Python自定义web框架、Jinja2
    Django初探(模板渲染、模板语音、simple_tag、母版子版、静态配置文件)
    多线程 threading
    python操作mysql
    sql 汉字转首字母拼音
    添加sql server约束
    NFS,Memcached,Tokyo tyrant实现session共享性能测试
    让Editplus自动格式化js、css、html。。。
    sql server中利用sql语句如何创建角色和用户
    asp网站文件夹权限设置
  • 原文地址:https://www.cnblogs.com/duojiaming/p/11298876.html
Copyright © 2011-2022 走看看