rqnoj28[stupid]愚蠢的宠物

题目描述

背景

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

描述

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

N的范围《=1000000

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

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

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

输出格式输出他们最早相遇的节点号。
样例输入
10
1 2
1 3
1 4
2 5
2 6
3 7
4 8
4 9
4 10
3 6

样例输出

1
#include<stdio.h>
#define N 1000001
inline void F(int &x){
    x=0;int c=getchar(),f=1;
    for(;c<48||c>57;c=getchar())
        if(!(c^45))
            f=-1;
    for(;c>47&&c<58;c=getchar())
        x=(x<<1)+(x<<3)+c-48;
    x*=f;
}
struct Pointer{int to;Pointer *nxt;}*fst[N];
inline void link(int u,int v){
    static Pointer mem[N<<1],*tot=mem;
    *++tot=(Pointer){v,fst[u]},fst[u]=tot;
    *++tot=(Pointer){u,fst[v]},fst[v]=tot;
}
bool vis[N];
int n,top[N],dep[N],fa[N],sz[N],hs[N];
void dfs_init(int x){
    sz[x]=vis[x]=1;
    for(Pointer *iter=fst[x];iter;iter=iter->nxt)
        if(!vis[iter->to]){
            fa[iter->to]=x,
            dep[iter->to]=dep[x]+1,
            dfs_init(iter->to),
            sz[x]+=sz[iter->to];
            if(sz[hs[x]]<sz[iter->to])
                hs[x]=iter->to;
        }
}
void dfs_make(int x){
    vis[x]=0;
    top[x]=x^hs[fa[x]]?x:top[fa[x]];
    if(hs[x]){
        dfs_make(hs[x]);
        for(Pointer *iter=fst[x];iter;iter=iter->nxt)
            if(vis[iter->to])
                dfs_make(iter->to);
    }
}
int lca(int x,int y){
    for(;top[x]^top[y];)
        dep[top[x]]>dep[top[y]]?
        x=fa[top[x]]:
        y=fa[top[y]];
    return dep[x]<dep[y]?x:y;
}
int main(){
    int x,y;
    F(n);
    for(int i=1;i<n;i++)
        F(x),
        F(y),
        link(x,y);
    dfs_init(1);
    dfs_make(1);
    F(x),
    F(y),
    printf("%d
",lca(x,y));
}
原文地址:https://www.cnblogs.com/keshuqi/p/6060714.html