LCA 板子
变量:
i
n
t
int
int
f
a
[
N
]
[
30
]
(
第二维取决于
N
大小,跳表
)
fa[N][30](第二维取决于N大小,跳表)
fa[N][30](第二维取决于N大小,跳表)
i
n
t
int
int
d
e
p
[
N
]
(
点深度
)
dep[N](点深度)
dep[N](点深度)
i
n
t
int
int
h
[
N
]
,
e
[
M
]
,
n
e
[
M
]
,
i
d
x
(
邻接表
)
h[N],e[M],ne[M],idx(邻接表)
h[N],e[M],ne[M],idx(邻接表)
求 求 求 d f s dfs dfs 序变量: 序变量: 序变量:
i
n
t
int
int
t
i
m
e
s
t
a
m
p
timestamp
timestamp
i
n
t
int
int
d
f
n
[
N
]
dfn[N]
dfn[N]
关键函数:
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
void bfs(int root){
memset(dep,0x3f,sizeof dep);
dep[root]=1;
dep[0]=0;//哨兵
queue<int>q;
q.push(root);
while(q.size()){
auto t=q.front();
q.pop();
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i];
if(dep[j]>dep[t]+1){
dep[j]=dep[t]+1;
q.push(j);
//预处理跳表
fa[j][0]=t;
for(int k=1;k<=25;k++){
fa[j][k]=fa[fa[j][k-1]][k-1];//倍增
}
}
}
}
}
int lca(int a,int b){
if(dep[a]<dep[b])swap(a,b);
//先让高dep跳到和低dep同一层
for(int k=25;k>=0;k--){
if(dep[fa[a][k]]>=dep[b])a=fa[a][k];//哨兵在此起作用
}
if(a==b)return a;//返回哪个都可以此时a和b表示的是同一个编号
//如果两个编号不相等,找最近公共祖先
for(int k=25;k>=0;k--){
if(fa[a][k]!=fa[b][k]){
a=fa[a][k];
b=fa[b][k];
}
}
return fa[a][0];
}
d f s 序函数 : dfs序函数: dfs序函数:
void dfs(int u,int fa){
dep[u]=dep[fa]+1;
f[u][0]=fa;dfn[u]=++timestamp;
for(int k=1;k<=20;k++)f[u][k]=f[f[u][k-1]][k-1];
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
if(j==fa)continue;
dfs(j,u);
}
}