Topic description
As in the question, given a rooted multi-fork tree, request the nearest common ancestor of the specified two points.
Input and output format
Input format:
The first line contains three positive integers N, M, and S, which represent the number of nodes in the tree, the number of queries, and the sequence number of the root node of the tree, respectively.
The next N-1 lines each contain two positive integers x and y, indicating that there is a directly connected edge between the x node and the y node (the data is guaranteed to form a tree).
Each of the next M lines contains two positive integers a and b, which means to ask the nearest common ancestor of node a and node b.
Output format:
The output contains M lines, each containing a positive integer, followed by the result of each query.
Input and output example
illustrate
Time and space limit: 1000ms, 128M
Data size:
For 30% of the data: N<=10, M<=10
For 70% of the data: N<=10000, M<=10000
For 100% data: N<=500000, M<=500000
Example description:
The tree structure is as follows:
The first query: the nearest common ancestor of 2 and 4, so it is 4.
The second query: the nearest common ancestor of 3 and 2, so it is 4.
The third query: the nearest common ancestor of 3 and 5, so it is 1.
The fourth query: the most recent common ancestor of 1 and 2, so it is 4.
The fifth query: the most recent common ancestor of 4 and 5, so it is 4.
So the output is 4, 4, 1, 4, 4 in sequence.
Ideas: lca board.
Tucao: So fake, I can only knock on the board.
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 500000 using namespace std; int n,m,tot,root; int to[MAXN*2],net[MAXN*2],head[MAXN]; int dad[MAXN],deep[MAXN],top[MAXN],size[MAXN]; void add(int u,int v){ to[++tot]=v;net[tot]=head[u];head[u]=tot; to[++tot]=u;net[tot]=head[v];head[v]=tot; } void dfs(int now){ size[now]=1; deep[now]=deep[dad[now]]+1; for(int i=head[now];i;i=net[i]) if(dad[now]!=to[i]){ dad[to[i]]=now; dfs(to[i]); size[now]+=size[to[i]]; } } void dfs1(int x){ int t=0; if(!top[x]) top[x]=x; for(int i=head[x];i;i=net[i]) if(dad[x]!=to[i]&&size[to[i]]>size[t]) t=to[i]; if(t){ top[t]=top[x]; dfs1(t); } for(int i=head[x];i;i=net[i]) if(dad[x]!=to[i]&&t!=to[i]) dfs1(to[i]); } int lca(int x,int y){ for(;top[x]!=top[y];){ if(deep[top[x]]<deep[top[y]]) swap(x,y); x=dad[top[x]]; } if(deep[x]>deep[y]) swap(x,y); return x; } int main(){ scanf("%d%d%d",&n,&m,&root); for(int i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); } dfs(root);dfs1(root); for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } } /* 5 5 4 3 1 2 4 5 1 1 4 2 4 3 2 3 5 1 2 4 5 */