您的位置:首页 > 其它

Codevs1036 商务旅行 LCA【pascal】

2016-11-15 07:20 483 查看
LCA模板题,注意是双向边=。=,而且是顺次经过m个城市

var
n,a,b,l,m,ans :longint;
i,j :longint;
vis :array[0..30010] of boolean;
last,d :array[0..30010] of longint;
pre,other :array[0..60010] of longint;
jump :array[0..30010,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
vis[p]:=true;
jump[p,0]:=x;
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;

procedure lca(x,y:longint);
var
p,q:longint;
i,j:longint;
begin
if (d[x]<d[y]) then swap(x,y);
for i:=0 to 15 do
if ((d[x]-d[y]) and (1<<i)<>0) then
begin
inc(ans,1<<i);
x:=jump[x,i];
end;
if (x<>y) then
begin
for i:=15 downto 0 do
if (jump[x,i]<>jump[y,i]) then
begin
inc(ans,2*(1<<i));
x:=jump[x,i];
y:=jump[y,i];
end;
inc(ans,2);
end;
end;

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