下面的是一个AC代码
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define re register
const int N=500005;
using namespace std;
int depth[N],parents[N][23];
int n,m,s,u,v,root;
struct node
{
int fa;
int number;
}now,endd;
queue <node> q;
vector <int> g[N];
il int read()
{
int f=0,s=0;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
for(;isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
return f ? -s : s;
}
il void bfs(int x)
{
now.fa=0;now.number=x;
q.push(now);
int num;
while(!q.empty())
{
now=q.front();
q.pop();
num=now.number;
for(int j=1;j<=22;j++)
parents[num][j]=parents[parents[num][j-1]][j-1];
for(int j=0;j<g[num].size();j++)
{
int e=g[num][j];
if(e==now.fa) continue;
depth[e]=depth[num]+1;
endd.number=e;
endd.fa=num;
parents[e][0]=num;
q.push(endd);
}
}
}
/*il void Multiply()
{
for(re int u=1;u<=n;u++)
for(re int up=1;up<=22;up++)
parents[u][up]=parents[parents[u][up-1]][up-1];
}*/
int LCA(int x,int y)
{
if(depth[x] < depth[y]) swap(x,y);
for(re int i=22;i>=0;i--)
if(depth[parents[x][i]] >= depth[y]) x=parents[x][i];
if(x == y) return x;
for(re int i=22;i>=0;i--)
{
if(parents[x][i] != parents[y][i])
{
x=parents[x][i];
y=parents[y][i];
}
}
return parents[x][0];
}
int main()
{
n=read(),m=read(),s=read();
// memset(parents,-1,sizeof parents);
// memset(depth,-1,sizeof depth);
for(re int i=1;i<=n-1;i++)
{
u=read(),v=read();
g[u].push_back(v);
g[v].push_back(u);
}
depth[s]=1;
parents[s][0]=0;
bfs(s);
//Multiply();
for(re int i=1;i<=m;i++)
{
u=read(),v=read();
printf("%d\n",LCA(u,v));
}
return 0;
}
我选择在bfs中进行初始化,下面是一个WA代码的部分片段
il void Multiply()
{
for(re int up=1;up<=22;up++)
for(re int u=1;u<=n;u++)
parents[u][up]=parents[parents[u][up-1]][up-1];
}
int LCA(int x,int y)
{
if(depth[x] < depth[y]) swap(u,v);
for(re int i=22;i>=0;i--)
if(depth[parents[x][i]] >= depth[y]) u=parents[x][i];
if(x == y) return x;
for(re int i=22;i>=0;i--)
{
if(parents[x][i] != parents[y][i])
{
x=parents[x][i];
y=parents[y][i];
}
}
return parents[x][0];
}
下面是另一个AC片段
void increase()
{
for(int up=1;(1<<up)<=n;up++)
for(int u=1;u<=n;u++)
parents[u][up]=parents[parents[u][up-1]][up-1];
}
int lca(int u,int v)
{
if(depth[u]<depth[v]) swap(u,v);
int maxjump=-1,j;
while((1<<(maxjump+1)) <= depth[u]) ++maxjump;
for(int i=maxjump;i>=0;i--)
if(depth[u]- (1<<i) >= depth[v]) u=parents[u][i];
if(u==v) return u;
for(int i=maxjump;i>=0;i--)
{
if(parents[u][i] != parents[v][i])
{
u=parents[u][i];
v=parents[v][i];
}
}
return parents[u][0];
}
int main()
{
...
depth[s]=1;
parents[s][0]=s;
search(s);
increase();
...
}
代码可能有点长。通过我的研究第二个代码的问题是在multiply函数中有可能我先遍历到的是儿子节点再是父亲节点,导致错误。于是我就选择了第一个代码的方式,在bfs中进行初始化 parents 数组,使其有序,然后就AC了。于是我翻出了我之前写的AC过的LCA模板,我依旧是用的Multiply函数,并且这个代码是AC的,我想请问是因为我在第三个代码中用了maxjump的原因使其不出错吗,如果不是,请问是什么原因导致的第二份代码和第三份代码的差异?