zoukankan      html  css  js  c++  java
  • 最近公共祖先

    【题目描述】:

    有根树在计算机科学工程领域是一个人人熟知的数据结构类型。下面是一个例子。

    8->(1,4,5);1->(13,14);4->(6,10);5->(9);6->(7,15);10->(2,11,16);16->(3,12);

    在这个图中,每个点都是由{1, 2,...,16}中的某个数字标记的。8号点是树的根。如果x号点在y号点到根的路径上,则x是y的祖先。比如4是16的祖先,10也是。事实上,8,4,10,16都是16的祖先。记住,一个节点本身就是自己的祖先。再比如8,4,6,7是7的祖先。

    如果x既是y的祖先也是z的祖先则称x是y和z公共祖先。也就是说8和4都是16和7的公共祖先。

    如果x在y和z的所有公共祖先中距离y和z最近,则x是y和z的最近公共祖先。也就是说4是16和7的最近公共祖先而不是8,因为4比8更近。

    再举一些例子:节点2和3的最近共同祖先是节点10,节点6和13的最近共同祖先是节点8,节点4和12的最近共同祖先是节点4。在最后一个例子中,如果Y是Z的祖先,那么Y和Z的最近共同祖先是Y。

    编写一个程序,找出树中两个不同节点的最近共同祖先。

    【输入描述】:

    第一行,N和M表示节点数和询问数,节点编号1至N;

    以下N-1行,每行两个整数a和b,表示a是b的父亲节点;

    之后M行,每行两个不相同的数,表示询问它们的最近共同祖先。

    【输出描述】:

    M行,每行一个数表示对应的询问结果。

    【样例输入】:

    16 1
    1 14
    8 5
    10 16
    5 9
    4 6
    8 4
    4 10
    1 13
    6 15
    10 11
    6 7
    10 2
    16 3
    8 1
    16 12
    16 7

    【样例输出】:

    4

    【时间限制、数据范围及描述】:

    时间:1s 空间:256M

    对于 40%的数据:1<=N,M<=3000

    对于 100%的数据:1<=N,M<=2×10^5

    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int Max=500005;
    
    int n,m,x,y,cnt,list[Max],s[Max],d[Max],f[Max],hhh[Max];
    
    int son[Max],c[Max];
    
    struct xo {
        int to,next;
    }a[4*Max];
    
    void add(int e,int r){ 
        a[++cnt].to=r; 
        a[cnt].next=list[e];
        list[e]=cnt; 
    } 
    
    inline int read(){
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-'){
                w=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            s=s*10+ch-'0';
            ch=getchar();
        }
        return s*w;
    }
    
    void dfs1(int n,int kkksc03){
        s[n]=1;
        d[n]=d[kkksc03]+1;
        f[n]=kkksc03;
        int kkksc04;
        for(int i=list[n];i;i=a[i].next) {
            kkksc04=a[i].to;
            if(kkksc04!=kkksc03) {
                dfs1(kkksc04,n);
                s[n]+=s[kkksc04];
                if(!son[x]||s[son[n]]<s[kkksc04]){
                    son[n]=kkksc04;
                }
            }
        }
    }
    
    void dfs2(int n,int kkksc03){
        c[n]=kkksc03;
        if(son[n]){
            dfs2(son[n],kkksc03);
        }
        else{
            return;
        }
        int kkksc04;
        for(int i=list[n];i;i=a[i].next) {
            kkksc04=a[i].to;
            if(kkksc04!=f[n]&&kkksc04!=son[n]){
                dfs2(kkksc04,kkksc04);
            }
        }
    }
    
    int lca(int a,int b){
        while(c[a]!=c[b]){
            if(d[c[a]]<d[c[b]]){
                swap(a,b);
            }
            a=f[c[a]];
        }
        return d[a]<d[b]?a:b;
    }
    
    int main(){
        int kkksc03;
        n=read();
        m=read();
        //kkksc03=read();
        for(int i=1;i<=n-1;i++){
            x=read();
            y=read();
            add(x,y);
            hhh[y]=x;
            add(y,x);
        }
        for(int i=1;i<=n;i++){
            if(hhh[i]==0){
                kkksc03=i;
                break;
            }
        }
        dfs1(kkksc03,0);
        dfs2(kkksc03,kkksc03);
        while(m--){
            x=read();
            y=read();
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
  • 相关阅读:
    Silverlight学习(五)图形标绘
    Silverlight学习(四) domainservice动态多条件查询
    MySQL之单表查询
    mysql外键的三种关系
    mysql之完整性约束
    接口类和抽象类的区别
    mysql中的sql_mode
    html5本地存储技术 localstorage
    mysql数值类型
    mysql
  • 原文地址:https://www.cnblogs.com/hrj1/p/11230991.html
Copyright © 2011-2022 走看看