LCA 板子
变量:
intintint fa[N][30](第二维取决于N大小,跳表)fa[N][30](第二维取决于N大小,跳表)fa[N][30](第二维取决于N大小,跳表)
intintint dep[N](点深度)dep[N](点深度)dep[N](点深度)
intintint h[N],e[M],ne[M],idx(邻接表)h[N],e[M],ne[M],idx(邻接表)h[N],e[M],ne[M],idx(邻接表)
求求求 dfsdfsdfs 序变量:序变量:序变量:
intintint timestamptimestamptimestamp
intintint dfn[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];
}
dfs序函数: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);
}
}