Tarjan LCA
http://blog.csdn.net/cdy1206473601/article/details/77104910
explain
I wrote Tarjan LCA last time, but when the tree is a chain, the time complexity is very high! So, we can solve it with multiplication. However, under random data, Tarjan is faster than doubling!
Well, the idea of doubling is to set a fa[i][j] to represent the first node of i
ancestors. Then you can use this fa array by solving upwards to achieve the multiplication effect.
Forming this fa array is done with a dfs. Transfer equation fa[i][j]=fa[fa[i][j-1]][j-1];
void dfs(int x)
{
fa[x][0]=f[x];
for (int i=1;i<=20;i++)
{
if (fa[x][i-1]<=1) break;
fa[x][i]=fa[fa[x][i-1]][i-1];
}
int i=last[x],yy=0;
vis[x]=true;
while (i)
{
yy=tov[i];
if (vis[yy]==false)
{
f[yy]=x;
deep[yy]=deep[x]+1;
dfs(yy);
}
i=next[i];
}
}
Then it's doubling, first looking for the depth of these two points, until the depths of the two points are equal~
int lca_len(int x,int y)
{
if (deep[x]<deep[y])
{
int t=x;
x=y;
y=t;
}
for (int i=20;i>=0;i--)//使其深度相等。
{
if (fa[x][i]!=0&&deep[y]<=deep[fa[x][i]])
x=fa[x][i];
if (x==y) break;
}
if (x==y) return x;
for (int i=20;i>=0;i--)
{
if (fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
if (x==y) break;
}
if (f[x]==f[y])
{
x=fa[x][0];
y=fa[y][0];
}
return x;//最后Lca就是它们本身啦。
}