题目描述
背景
大家都知道,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)); }