[luogu-3379]【模板】最近公共祖先(LCA) 题解

来源:互联网 发布:大数据培训靠谱吗 编辑:程序博客网 时间:2024/05/18 05:44

题目传送门
模板题,没什么好说的。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define rep(i,a,n) for (int i=a;i<=n;i++)#define per(i,a,n) for (int i=a;i>=n;i--)#define Clear(a,x) memset(a,x,sizeof(a))#define ll long long#define INF 2000000000#define eps 1e-8using namespace std;int read(){    int x=0,f=1;    char ch=getchar();    while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar();    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}const int maxn=500005;int ans[maxn],anc[maxn],f[maxn],flag[maxn];int n,m,root;struct node{    int vet[maxn<<1],next[maxn<<1],head[maxn],road[maxn<<1];    int len;    void add(int u,int v,int w){        vet[++len]=v;        next[len]=head[u];        head[u]=len;        road[len]=w;    }}edge,edge_q;int find(int k){    return f[k]==k?k:f[k]=find(f[k]);}void Union(int x,int y){    int xx=find(x),yy=find(y);    f[xx]=yy;}void dfs(int u){    anc[find(u)]=u;    flag[u]=1;    for (int e=edge.head[u];e;e=edge.next[e]){        int v=edge.vet[e];        if (flag[v]) continue;        dfs(v);        Union(u,v);        anc[find(u)]=u;    }    flag[u]=2;    for (int e=edge_q.head[u];e;e=edge_q.next[e]){        int v=edge_q.vet[e];        int i=edge_q.road[e];        if (flag[v]==2){            int x=anc[find(v)];            ans[i]=x;        }    }}int main(){    n=read(),m=read(),root=read();    rep(i,1,n-1){        int u=read(),v=read();        edge.add(u,v,0),edge.add(v,u,0);    }    rep(i,1,m){        int u=read(),v=read();        edge_q.add(u,v,i),edge_q.add(v,u,i);    }    rep(i,1,n) f[i]=i;    dfs(root);    rep(i,1,m) printf("%d\n",ans[i]);    return 0;}