• Codevs 1503 愚蠢的宠物


    1503 愚蠢的宠物

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
     
     
    题目描述 Description

    大家都知道,sheep有两只可爱的宠物(一只叫神牛,一只叫神菜)。有一天,sheep带着两只宠物到狗狗家时,这两只可爱的宠物竟然迷路了……

    狗狗的家因为常常遭到猫猫的攻击,所以不得不把家里前院的路修得非常复杂。狗狗家前院有N个连通的分叉结点,且只有N-1条路连接这N个节点,节点的编号是1-N(1为根节点)。sheep的宠物非常笨,他们只会向前走,不会退后(只向双亲节点走),sheep想知道他们最早什么时候会相遇(即步数最少)。

    输入描述 Input Description

    第1行:一个正整数N,表示节点个数。

    第2~N行:两个非负整数A和B,表示A是B的双亲。(保证A,B<=n)

    第N+1行:两个非负整数A和B,表示两只宠物所在节点的位置。(保证A,B<=n)

    输出描述 Output Description

    输出他们最早相遇的节点号。

    样例输入 Sample Input

    10
    1 2
    1 3
    1 4
    2 5
    2 6
    3 7
    4 8
    4 9
    4 10
    3 6

    样例输出 Sample Output

    1

    数据范围及提示 Data Size & Hint

    对于10%的数据,n<10^6

    对于100%的数据,n<=10^6

    /*
       lca能解决的事为什么要贴上搜索的标签。。
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define maxn 1000010
    int n,s1,s2,head[maxn*2],num,son[maxn],sz[maxn],top[maxn],fa[maxn],dep[maxn];
    struct node{
        int to,pre;
    }e[maxn*2];
    void Insert(int from,int to){
        e[++num].to=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    void dfs1(int u,int father){
        sz[u]=1;
        fa[u]=father;
        dep[u]=dep[father]+1;
        for(int i=head[u];i;i=e[i].pre){
            int v=e[i].to;
            if(v==father)continue;
            dfs1(v,u);
            sz[u]+=sz[v];
            if(!son[u]||sz[v]>sz[son[u]])son[u]=v;
        }
    }
    void dfs2(int u,int father){
        top[u]=father;
        if(son[u])dfs2(son[u],father);
        else return;
        for(int i=head[u];i;i=e[i].pre){
            int v=e[i].to;
            if(v==fa[u]||v==son[u])continue;
            dfs2(v,v);
        }
    }
    int lca(int x,int y){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            x=fa[top[x]];
        }
        if(dep[x]<dep[y])return x;
        else return y;
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d",&n);
        int x,y;
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            Insert(y,x);
            Insert(x,y);
        }
        scanf("%d%d",&s1,&s2);
        dfs1(1,0);
        dfs2(1,1);
        printf("%d",lca(s1,s2));
    }
    树剖 lca
  • 相关阅读:
    C++学习(一)之Visual Studio安装以及首次使用
    基于BP的B/S架构破解
    铁三测试题——权限、你是管理员吗?——WP
    实验吧—安全杂项——WP之 flag.xls
    实验吧—安全杂项——WP之 女神
    wireshark显示过滤器的几种用法(转自他人博客)
    实验吧—安全杂项——WP之 你知道他是谁吗?
    实验吧—Web——WP之 FALSE
    实验吧—Web——WP之 Guess Next Session
    实验吧—Web——WP之 简单的sql注入之2
  • 原文地址:https://www.cnblogs.com/thmyl/p/7218889.html
Copyright © 2020-2023  润新知