zoukankan      html  css  js  c++  java
  • SP14932 LCA

    Description:

    一棵树是一个简单无向图,图中任意两个节点仅被一条边连接,所有连通无环无向图都是一棵树。(-Wikipedia)

    最近公共祖先((LCA))是……(此处省去对(LCA)的描述),你的任务是对一棵给定的树(T)以及上面的两个节点(u,v)求出他们的(LCA)

    例如图中9和12号节点的LCA为3号节点

    Input:

    输入的第一行为数据组数(T),对于每组数据,第一行为一个整数(N(1leq Nleq1000)),节点编号从(1)(N),接下来的(N)行里每一行开头有一个数字(M(0leq Mleq999))(M)为第(i)个节点的子节点数量,接下来有(M)个数表示第(i)个节点的子节点编号。下面一行会有一个整数(Q(1leq Qleq1000)),接下来的(Q)行每行有两个数(u,v),输出节点(u,v)在给定树中的(LCA)

    输入数据保证只有一个根节点并且没有环。

    Output:

    对于每一组数据输出(Q+1)行,第一行格式为("Case i:")(没有双引号),(i)表示当前数据是第几组,接下来的(Q)行每一行一个整数表示一对节点(u,v)(LCA)

    Sample Input:

    1
    7
    3 2 3 4
    0
    3 5 6 7
    0
    0
    0
    0
    2
    5 7
    2 7
    

    Sample Output:

    Case 1:
    3
    1
    

    (Translated by @_yxl_g)l_

    思路:一道求(LCA)的板子题,根据题目给出的每个点的孩子建边然后找出根结点,直接(dfs)求出深度后跑(LCA)就可以了。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 1007
    using namespace std;
    int t,q,rt,tim,f[maxn][22],n,m,head[maxn],d[maxn],num;
    bool vis[maxn];
    struct node {
      int v,nxt;
    }e[maxn<<1];
    inline void ct(int u, int v) {
      e[++num].v=v;
      e[num].nxt=head[u];
      head[u]=num;
    }
    void dfs(int u, int fa) {
      for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v!=fa) {
          f[v][0]=u;
          d[v]=d[u]+1;
          dfs(v,u);
        }
      }
    }
    inline int lca(int a, int b) {
      if(d[a]>d[b]) swap(a,b);
      for(int i=20;i>=0;--i) 
      if(d[a]<=d[b]-(1<<i)) b=f[b][i];
      if(a==b) return a;
      for(int i=20;i>=0;--i)
      if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];
      return f[a][0];
    }
    int main() {
      scanf("%d",&t);
      while(t--) {
        ++tim;
        memset(f,0,sizeof(f));
        memset(d,0,sizeof(d));
        memset(head,0,sizeof(head));
        memset(vis,0,sizeof(vis));
        num=0;
        scanf("%d",&n);
        for(int i=1,m;i<=n;++i) {
          scanf("%d",&m);
          for(int j=1,v;j<=m;++j) {
            scanf("%d",&v);
            ct(i,v);ct(v,i);
            vis[v]=1;
          }
        }
        for(int i=1;i<=n;++i) if(!vis[i]) rt=i;
        dfs(rt,0);
        for(int j=1;j<=20;++j)
        for(int i=1;i<=n;++i)
        f[i][j]=f[f[i][j-1]][j-1];
        scanf("%d",&q);
        printf("Case %d:
    ",tim);
        for(int i=1,u,v;i<=q;++i) {
          scanf("%d%d",&u,&v);
          printf("%d
    ",lca(u,v));
        }
      }
      return 0;
    }
    
  • 相关阅读:
    Codeforces Gym100502H:Clock Pictures(KMP算法)
    SPOJ MINSUB
    POJ 2796:Feel Good(单调栈)
    搭建(WSTMart)php电商环境时缺少fileinfo函数
    TP微信扫码支付
    tp3.2 支付宝app支付
    tp3.2 支付宝手机网站支付
    Thinkphp3.2+PHPQRCode 二维码生成示例
    百度UEditor粘贴或插入的表格不显示边框的解决办法
    PHP:导出数据到word(包含图片)
  • 原文地址:https://www.cnblogs.com/grcyh/p/10153913.html
Copyright © 2011-2022 走看看