LCA有两种
一种是Tarjan-LCA
是一种离线算法
是在树的深搜的基础上进行的~
哎呀发现不想说什么> <
具体思想见程序> <
当然了我们还有一种在线的算法
利用倍增思想
f[i,j]表示
即设i点向上走2^j步后到了哪里
deep[i]表示i的深度
可以做到O(nlgn)的预处理,以及O(lgn)的查询
~
一种是Tarjan-LCA
是一种离线算法
是在树的深搜的基础上进行的~
哎呀发现不想说什么> <
具体思想见程序> <
理论上是O(N),但由于调用系统栈所以常数会有点大~
procedure TarjanLCA(u:longint);
var i:longint;
begin
father[u]:=u;
i:=headlist[u];
while i<>-1 do
begin
TarjanLCA(t[i]);
merge(t[i],u);
i:=next[i];
end;
visited[u]:=true;
for i:=1 to ask[u,0] do
if visited[ask[u,i]] then ans[u,i]:=find(ask[u,i]);
end;
当然了我们还有一种在线的算法
利用倍增思想
f[i,j]表示
即设i点向上走2^j步后到了哪里
deep[i]表示i的深度
可以做到O(nlgn)的预处理,以及O(lgn)的查询
procedure dfs(u:longint);
begin
for i:=1 to maxlen do f[u,i]:=f[f[u,i-1],i-1];
i:=headlist[u];
while i<>-1 do
begin
deep[t[i]]:=deep[u]+1;
dfs(t[i]);
i:=next[i];
end;
end;
function ask(a,b:longint):longint;
var i,del:longint;
begin
if deep[a]>deep[b] then begin
t:=a;
a:=b;
b:=t;
end;
del:=deep[b]-deep[a];
for i:=0 to maxlen do if (del and (1 shl i))<>0 then b:=f[b,i];
if a<>b then begin
for i:=maxlen downto 0 do
if f[b,i]<>f[a,i] then begin
a:=f[a,i];
b:=f[b,i];
end;
a:=f[a,0];
b:=f[b,0];
end;
exit(a);
end;
~