LCA

21 篇文章 0 订阅
4 篇文章 0 订阅
LCA有两种
一种是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;

~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值