1. 程式人生 > >Luogu P3379 【模板】最近公共祖先(LCA)

Luogu P3379 【模板】最近公共祖先(LCA)

col tdi www pac div 祖先 http https 最近公共祖先

qwq

懶得寫了明天補

為啥不開兩倍會re啊

代碼

#include<cstdio>
#include<iostream>
#include<cmath>
#define MogeKo qwq

using namespace std;
const int maxn = 500005*2;
int head[maxn],to[maxn],nxt[maxn],dpth[maxn];
int n,m,s,u,v,cnt,p[maxn][30];


void add(int x,int y) {
    to[++cnt] = y;
    nxt[cnt] = head[x];
    head[x] 
= cnt; } void dfs(int x,int fa) { dpth[x] = dpth[fa]+1; p[x][0] = fa; for(int i = 1; (1 << i)<=dpth[x]; i++) p[x][i] = p[p[x][i-1]][i-1]; for(int i = head[x]; i; i = nxt[i]) { if(to[i] == fa)continue; dfs(to[i],x); } } int lca(int a,int b) {
if(dpth[a] < dpth[b]) swap(a,b); for(int i = log2(dpth[a]); i >= 0; i--) if(dpth[a]-(1<<i) >= dpth[b]) a = p[a][i]; if(a == b)return a; for(int i = log2(dpth[a]);i >= 0;i--) if(p[a][i] != p[b][i]){ a = p[a][i]; b
= p[b][i]; } return p[a][0]; } int main() { scanf("%d%d%d",&n,&m,&s); for(int i = 1;i <= n-1;i++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(s,-1); for(int i = 1;i <= m;i++){ scanf("%d%d",&u,&v); int t = lca(u,v); printf("%d\n",t); } return 0; }

Luogu P3379 【模板】最近公共祖先(LCA)