zoukankan      html  css  js  c++  java
  • [noip模拟]祖孙询问<LCA>

    【问题描述】

     

        已知一棵n个节点的有根树。有m个询问。每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系。

    【输入格式】

        输入第一行包括一个整数n表示节点个数。

        接下来n行每行一对整数对a和b表示a和b之间有连边。如果b是-1,那么a就是树的根。

        第n+2行是一个整数m表示询问个数。

        接下来m行,每行两个正整数x和y。

    【输出格式】

        对于每一个询问,输出1:如果x是y的祖先,输出2:如果y是x的祖先,否则输出0。

    【样例输入】

    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

    【样例输出】

    1

    0

    0

    0

    2

    【数据规模】

        对于30%的数据,n,m≤1000。

        对于100%的.据,n,m≤40000,每个节点的编号都不超过40000。

     

     

    这是去年我们考的一套题,现在回过头来看,其实不难啊,谁知道当年还做的要死要活的

    这题就是一个裸的LCA,毕竟题目都这样说了

    我用了tarjan,因为个人来说我的tarjan打的要差一些,但是打了这题后,我对tarjan求LCA的理解要正常的许多了

    裸的tarjan,额外处理就是储存一个对每一个询问边的最近公共祖先,但是我们建立询问边是建立了两条,所以要注意在储存答案时要合并起来

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdlib>
     6 #include<queue>
     7 #include<cmath>
     8 #define maxn 40005
     9 using namespace std;
    10 
    11 struct node{
    12     int u,v,nxt;
    13 }e[maxn*4],p[maxn*4];
    14 
    15 int n,m,dfn[maxn],fa[maxn],belong[maxn],root,maxid;
    16 int head[maxn],heap[maxn],vis[maxn*4],visid[maxn];
    17 int ord[maxn*4];
    18 
    19 int tot;
    20 void adde(int u,int v){e[tot]=(node){u,v,head[u]};head[u]=tot++;}
    21 
    22 int tpt;
    23 void addp(int u,int v,int pos){p[tpt]=(node){u,v,heap[u]};
    24 ord[tpt]=pos;heap[u]=tpt++;
    25 }
    26 
    27 int find(int x){if(fa[x]==x)return x;return fa[x]=find(fa[x]);}
    28 
    29 int num;
    30 void tarjan(int u,int from){
    31     dfn[u]=++num;
    32     for(int i=head[u];i!=-1;i=e[i].nxt ){
    33         int v=e[i].v;
    34         if(!dfn[v]){tarjan(v,u);fa[v]=u;visid[v]=1;}
    35     }
    36     for(int i=heap[u];i!=-1;i=p[i].nxt){
    37         int vv=p[i].v;
    38         if(visid[vv]&&!vis[ord[i]]){vis[ord[i]]=find(vv);}
    39     }
    40 }
    41 
    42 int main(){
    43     freopen("tarjanlca.txt","r",stdin);
    44     memset(head,-1,sizeof(head));
    45     memset(heap,-1,sizeof(heap));
    46     scanf("%d",&n);
    47     for(int i=1;i<=n;i++){
    48         int u,v;scanf("%d%d",&u,&v);
    49         if(v==-1){root=u;continue;}
    50         adde(u,v);adde(v,u);maxid=max(maxid,max(u,v));
    51     }
    52     for(int i=1;i<=maxid;i++)fa[i]=i;
    53     scanf("%d",&m);
    54     for(int i=1;i<=m;i++){
    55         int u,v;scanf("%d%d",&u,&v);
    56         addp(u,v,i);addp(v,u,i);
    57     }visid[root]=1;
    58     tarjan(root,0);
    59     for(int i=1;i<=m;i++){
    60         int lca=vis[i],pos=(i-1)*2;
    61         if(lca==p[pos].u ) puts("1");
    62         else if(lca==p[pos].v )puts("2");
    63         else puts("0");
    64     }
    65 }
    View Code

    【总结】

    tarjan大法好,可惜皮不来啊

  • 相关阅读:
    构建可靠的系统
    netty详解之reactor模型
    netty详解之io模型
    小明的魔法调度框架之旅
    JAVA版-微信高清语音.speex转.wav格式
    Spring Data JPA 缓存结合Ehcache介绍
    @media print样式 关于table断页
    JBPM学习第6篇:通过Git导入项目
    JBPM学习第5篇:Mysql配置
    JBPM学习第4篇:10分钟熟悉Eclipse
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7810704.html
Copyright © 2011-2022 走看看