zoukankan      html  css  js  c++  java
  • 9018:1892: 最近公共祖先用Tarjan来做

    题目描述

    编写一个程序,查找一棵含有n个节点的树中m组两个不同节点的最近公共祖先。

    输入

    第一行两个整数n和q,为树上节点的数目和查询数。节点标号为整数 1,2,...,n。之后n-1行每一行包含一对整数,代表边——第一个整数是第二个整数的父节点。请注意,一个具有n个节点的树有n-1条边。之后q行查询,每行两个整数,表示要查询的两个节点的标号。(输入保证有且只有一棵树)

    输出

    q行,每行一个整数,为此次查询的最近公共祖先的标号

    样例输入

    5 6
    2 5
    2 3
    5 1
    1 4
    1 3
    2 3
    5 4
    1 5
    4 5
    5 4

    样例输出

    2
    2
    5
    5
    5
    5
    

    提示

    2<=n,m<=5*10^5

     代码

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    # define INF 500010
    struct edge{int nx,t;}e[INF*3+1];
    int h[INF],q[INF],count,ans[INF],f[INF],r[INF];
    inline void ins(int*h,int x,int y){e[++count]=(edge){h[x],y};h[x]=count;}
    int gf(int k){return f[k]?f[k]=gf(f[k]):k;}
    void tj(int x){
      int i;
      for(i=q[x];i;i=e[i].nx)
        if(ans[e[i].t])ans[e[i].t]=gf(ans[e[i].t]);//最后一个ans
        else ans[e[i].t]=x;
      for(i=h[x];i;i=e[i].nx)tj(e[i].t),f[e[i].t]=x;
    }
    int main(){
      int m,n;
      scanf("%d%d",&n,&m);
      int i,x,y;
      for(i=1;i<n;++i){scanf("%d",&x);scanf("%d",&y);r[y]=1;ins(h,x,y);}//++i,怎样输入
      for(i=0;i<m;++i){scanf("%d",&x);scanf("%d",&y);ins(q,x,i);ins(q,y,i);}//++i,怎样输入
      for(i=1;i<=n;++i){if(!r[i]){tj(i);break;}}//!,++i
      for(i=0;i<m;++i)printf("%d ",ans[i]);// ++i
    }

    总结:一定要仔细

  • 相关阅读:
    《编写可维护的JavaScript》读书笔记
    第十四天:还是看代码
    第十三天:过了一遍rt_thread,看代码架构
    第十二天:rt_thread系统
    第十一天:要做stm32了
    第十天:没太专注工作
    第九天:rtc问题查找与测试
    第八天:android编译环境搭建
    第七天:终于看到板子了
    第六天和周末:感慨下这周
  • 原文地址:https://www.cnblogs.com/linzeli/p/6714404.html
Copyright © 2011-2022 走看看