您的位置:首页 > 其它

lca(最近公共祖先)倍增模板【pascal】

2016-11-14 21:37 323 查看
var
n,m,root,x,y,l  :longint;
i,j             :longint;
last,d          :array[0..500010] of longint;
vis             :array[0..500010] of boolean;
pre,other       :array[0..1000010] of longint;
jump            :array[0..500010,0..20] of longint;

procedure connect(x,y:longint);
begin
inc(l);
pre[l]:=last[x];
last[x]:=l;
other[l]:=y;
end;

procedure dfs(x:longint);
var
p,q:longint;
begin
q:=last[x];
while (q<>0) do
begin
p:=other[q];
if not vis[p] then
begin
jump[p,0]:=x;
vis[p]:=true;
d[p]:=d[x]+1;
dfs(p);
end;
q:=pre[q];
end;
end;

procedure swap(var a,b:longint);
var
c:longint;
begin
c:=a;a:=b;b:=c;
end;

function lca(x,y:longint):longint;
var
j:longint;
begin
if (d[x]>d[y]) then swap(x,y);
for j:=0 to 15 do
if  ((d[y]-d[x]) and (1<<j)<>0) then y:=jump[y,j];
//
if (x=y) then exit(x);
if (x<>y) then
begin
for j:=15 downto 0 do
if (jump[x,j]<>jump[y,j]) then
begin
x:=jump[x,j];y:=jump[y,j];
end;
end;
exit(jump[x,0]);
end;

begin
read(n,m,root);
for i:=1 to m-1 do
begin
read(x,y);
connect(x,y);
connect(y,x);
end;
//
d[root]:=1;vis[root]:=true;dfs(root);
for j:=1 to 15 do
for i:=1 to n do jump[i,j]:=jump[jump[i,j-1],j-1];
//
for i:=1 to m do
begin
read(x,y);
writeln(lca(x,y));
end;
end.
——by Eirlys
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图论 模板