zoukankan      html  css  js  c++  java
  • BUPT复试专题—最近公共祖先(2014软院)

    题目描述

    给出一棵有N个节点的有根树TREE(根的编号为1),对于每组查询,请输出树上节点u和v的最近公共祖先。 
    最近公共祖先:对于有向树TREE的两个结点u,v。最近公共祖先LCA(TREE u,v)表示一个节点x,满足x是u、v的祖先且x的深度尽可能大。

    输入

    输入数据第一行是一个整数T(1<=T<=100),表示测试数据的组数。 
    对于每组测试数据: 
    第一行是一个正整数N(1<=N<=100),表示树上有N个节点。 
    接下来N-1行,每行两个整数u,v(1<=u,v<=N),表示节点u是v的父节点。 
    接下来一行是一个整数M(1<=M<=1000),表示查询的数量。 
    接下来M行,每行两个整数u,v(11<=u,v<=N),表示查询节点u和节点v的最近公共祖先。 

    输出

    对于每个查询,输出一个整数,表示最近公共祖先的编号, 

    样例输入

    2 
    3 
    1 2 
    1 3 
    1 
    2 3 
    4 
    1 2 
    1 3 
    3 4 
    2 
    2 3 
    3 4 
    1 
    1 
    3

    样例输出

    1
    1
    3

    来源

    2014软院C题 

    数据量较大,直接上输入输出外挂

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<map>
    #define within(x,a,b) ((unsigned)((x)-(a))<=((b)-(a)))
    using namespace std;
    int readint(int *p)
    {
        int ch;
        while(!within(ch=getchar(),'0','9'))
            if(ch == EOF) return EOF;
        int rslt = 0;
        do
            rslt=rslt*10+(ch-'0');
        while(within(ch=getchar(),'0','9'));
        *p = rslt;
        return 1;
    }
    int println_int(int i)
    {
        char s[107], p=0;
        while(i){
            s[p++] = i%10;
            i/=10;
        }
        while(p) putchar('0'+s[--p]);
        putchar('
    ');
    }
    struct tree
    {
        int father;
        int floor;
    };
    map< int,tree > donser;
    int deal(int m,int n)
    {
        int floor_max=max(donser[m].floor,donser[n].floor);
        int floor_min=min(donser[m].floor,donser[n].floor);
        int x,y;
        if(donser[m].floor>donser[n].floor) //x->深的 
        {
            x=m;y=n;
        }
        else
        {
            x=n;y=m;
        }
        while(floor_max!=floor_min)
        {
            x=donser[x].father;
            floor_max--;
        }
        if(x==y)
            return y;
        else
        {
            while(x!=y)
            {
                x=donser[x].father;
                y=donser[y].father;
            }
            return y;
        }
    }
    int main()
    {
        int tes,num,shit;
        while(~scanf("%d",&tes))
        {
            while(tes--)
            {
                readint(&num);
                //cin>>num;
                donser[0].father=-1;
                donser[0].floor=1;
                num--;
                while(num--)
                {
                    int x,y;
                    readint(&x);
                    readint(&y);
                    //cin>>x>>y;
                    donser[y].father=x;
                    donser[y].floor=donser[x].floor+1;
                }
                //cin>>shit;
                readint(&shit);
                while(shit--)
                {
                    int m,n;
                    readint(&m);
                    readint(&n);
                    //cin>>m>>n;
                    println_int(deal(m,n));
                }
            }
             
        }
        return 0;
    }
  • 相关阅读:
    android用户界面之WebView教程实例汇总
    android用户界面之TabHost教程实例汇总
    手把手教你写android项目@第一期项目——身份证查询创新(项目总结)
    android用户界面之GridView教程实例汇总
    android学习从模仿开始 —— 模仿UI 导航帖
    Android 实现书籍翻页效果
    android用户界面之Widget教程实例汇总
    如何安装webdriver chrome浏览器支持
    Seleniumwebdriver系列教程(15)————使用已存在的profile启动firefox
    ruby设计模式之【观察者】模式1————简单的观察者模式
  • 原文地址:https://www.cnblogs.com/dzzy/p/8651773.html
Copyright © 2011-2022 走看看