Luogu P3379 【Template】Last Common Ancestor (LCA)

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

Input Example #1:  Copy
5 5 4
3 1
2 4
5 1
1 4
2 4
3 2
3 5
1 2
4 5
Output Sample #1:  Copy
4
4
1
4
4

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
*/

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325078717&siteId=291194637