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
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
相关文章推荐
- codevs 1036 商务旅行 (LCA)
- codevs1036商务旅行(LCA)
- 【LCA 倍增法】【codevs 1036 商务旅行】
- codevs 1036 商务旅行 (lca)
- CODE[VS] 1036 商务旅行(LCA + BFS)
- 【codevs1036】商务旅行,LCA练习
- codevs 1036 商务旅行(Targin求LCA)
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
- 倍增LCA code[vs]1036商务旅行
- 倍增法-lca codevs 1036 商务旅行
- 商务旅行_codevs1036_lca
- 【基础练习】【倍增LCA】codevs1036 商务旅行题解
- codevs 1036 商务旅行 (倍增LCA)
- codevs 1036 商务旅行
- 【CodeVS1036】商务旅行
- codevs1036 商务旅行 lcs倍增
- CodeVs 1036 商务旅行
- Codevs P1036 商务旅行
- Codevs 1036 商务旅行
- [CodeVS1036] 商务旅行