https://www.luogu.org/problemnew/show/SP14932
思路:先遍历一遍得到欧拉序,然后根据询问找到对应节点在欧拉序第一次出现的位置.left, right,然后欧拉序中在left到right之间的深度最小的节点就是LCA。
如上图:
从4遍历得到的欧拉序是 4 2 4 1 3 1 5 1 4
得到的对应节点深度 1 2 1 2 3 2 3 2 1
比如查询3 和 2 的最近公共祖先,3 和 2 在欧拉序中第一次出现的位置 是 2 和 5 ,在欧拉序中他们之间的点(包括自己)有
2 4 1 3 ,深度最小是 1 ,即 节点4。所以3 和2 的LCA是4
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn = 5e5 + 5;
const int maxbit = 20;
vector<int>G[maxn];
int order[maxn * 4];//记录欧拉序
int depth[maxn * 4];//记录欧拉序序列每个点的深度
int n,m,s;//节点个数,询问次数,根节点
int lg[maxn * 4];//以2为底向下取整
int ST[maxn * 4][maxbit];//记录长度是2的p次方的欧拉序列的深度最小的下标
int cnt = 0;//记录在欧拉序是第几个
int first_place[maxn * 4];//记录i节点第一次出现的位置
void dfs(int nownode, int fdepth)//确定欧拉序每个节点的深度和第一次出现的位置
{
//nownode是当前节点,fdepth是其父节点深度
cnt++;
first_place[nownode] = cnt;//欧拉序第cnt个节点的深度
order[cnt] = nownode;//欧拉序第cnt个节点是nownode
depth[cnt] = fdepth +1;//欧拉序第cnt个节点(即当前节点)深度为父节点深度+1
for(int i = 0; i < G[nownode].size(); i++)
{
int sonnode = G[nownode][i];
if(first_place[sonnode] == 0)//没有遍历过的子节点
{
dfs(sonnode, fdepth + 1);
cnt++;//欧拉序的回溯也要记录
order[cnt] = nownode;//同上
depth[cnt] = fdepth + 1;//同上
}
}
}
void ST_init()//建ST表
{
//初始每个节点都是深度最小的节点
for(int i = 1; i <= cnt; i++)
ST[i][0] = i;
int a, b;
for(int j = 1; j <= lg[cnt]; j++)
{
for(int i = 1; i + (1<<j) - 1 <= cnt; i++)
{
a = ST[i][j - 1];
b = ST[i + ( 1<<(j - 1) ) ][ j-1];
if(depth[a] < depth[b])
ST[i][j] = a;//记录深度最小节点
else
ST[i][j] = b;
}
}
}
int main()
{
ios::sync_with_stdio(false);
lg[0] = -1;//初始对数
for(int i = 1; i < maxn * 4; i++)
lg[i] = lg[i>>1] +1;
scanf("%d%d%d", &n, &m, &s);
int x, y;
for(int i = 0; i < n-1; i++)//构造图
{
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs(s, 0);
ST_init();
while(m--)
{
scanf("%d%d", &x, &y);
x = first_place[x];
y = first_place[y];
if(x > y)
swap(x, y);
int k = (y - x) + 1;
k = lg[k];
int a, b;
a = ST[x][k];
b = ST[y - (1<<k) + 1][k];
if(depth[a] < depth[b])
{
printf("%d\n", order[a]);
}
else
printf("%d\n", order[b]);
}
//system("pause");
}
来源:https://blog.csdn.net/qq_40722582/article/details/95968364