codevs2370 lca倍增
2016-11-15 07:33
381 查看
带边权的lca,加一个dis数组维护就可以,
dis数组同样用倍增累加求出:dis[i,j]=dis[i,j-1]+dis[jump[i,j-1],j-1]
var
n,a,b,l,m,ans,c :longint;
i,j :longint;
vis :array[0..50010] of boolean;
last,d :array[0..50010] of longint;
pre,other,len :array[0..100010] of longint;
jump,dis :array[0..50010,0..20] of longint;
procedure connect(x,y,z:longint);
begin
inc(l);
pre[l]:=last[x];
last[x]:=l;
other[l]:=y;
len[l]:=z;
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;
dis[p,0]:=len[q];
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
ans:=0;
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,dis[x,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,dis[x,i]);
inc(ans,dis[y,i]);
x:=jump[x,i];
y:=jump[y,i];
end;
inc(ans,dis[x,0]);
inc(ans,dis[y,0]);
end;
end;
begin
read(n);
for i:=1 to n-1 do
begin
read(a,b,c);
connect(a,b,c);
connect(b,a,c);
end;
d[1]:=1;vis[1]:=true;dfs(1);
for j:=1 to 15 do
for i:=1 to n do
begin
jump[i,j]:=jump[jump[i,j-1],j-1];
dis[i,j]:=dis[i,j-1]+dis[jump[i,j-1],j-1];//
end;
read(m);
for i:=1 to m do
begin
read(a,b);
lca(a,b);
writeln(ans);
end;
end.
——by Eirlys
dis数组同样用倍增累加求出:dis[i,j]=dis[i,j-1]+dis[jump[i,j-1],j-1]
var
n,a,b,l,m,ans,c :longint;
i,j :longint;
vis :array[0..50010] of boolean;
last,d :array[0..50010] of longint;
pre,other,len :array[0..100010] of longint;
jump,dis :array[0..50010,0..20] of longint;
procedure connect(x,y,z:longint);
begin
inc(l);
pre[l]:=last[x];
last[x]:=l;
other[l]:=y;
len[l]:=z;
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;
dis[p,0]:=len[q];
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
ans:=0;
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,dis[x,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,dis[x,i]);
inc(ans,dis[y,i]);
x:=jump[x,i];
y:=jump[y,i];
end;
inc(ans,dis[x,0]);
inc(ans,dis[y,0]);
end;
end;
begin
read(n);
for i:=1 to n-1 do
begin
read(a,b,c);
connect(a,b,c);
connect(b,a,c);
end;
d[1]:=1;vis[1]:=true;dfs(1);
for j:=1 to 15 do
for i:=1 to n do
begin
jump[i,j]:=jump[jump[i,j-1],j-1];
dis[i,j]:=dis[i,j-1]+dis[jump[i,j-1],j-1];//
end;
read(m);
for i:=1 to m do
begin
read(a,b);
lca(a,b);
writeln(ans);
end;
end.
——by Eirlys
相关文章推荐
- [POJ 1330][CodeVS 2370]LCA 倍增
- 倍增lca学习笔记(codevs2370小机房的树题解)
- codevs —— 2370 小机房的树 倍增LCA
- 【日常学习】【倍增LCA】codevs2370 小机房的树题解
- Codevs 2370 小机房的树 LCA 树上倍增
- LCA(倍增在线算法) codevs 2370 小机房的树
- 【基础练习】【倍增LCA】codevs1503 愚蠢的宠物
- NOIP 2013 CODE[VS] 3287 货车运输 倍增LCA + 最大生成树
- 【LCA 倍增法】【codevs 1036 商务旅行】
- Code[VS] 2370 LCA 题解
- CODE[VS] 2370 小机房的树 暴力求解LCA
- 【codevs2370】小机房的树,RMQ求LCA
- [LCA][CODEVS 2370]小机房的树
- 倍增LCA code[vs]1036商务旅行
- NOIP 2013 CODE[VS] 3287 货车运输 倍增LCA || 暴力LCA + 最大生成树
- CodeVS 2370 LCA 解题报告
- codevs 2370 小机房的树(lca)
- <倍增lca>codevs 3305 水果姐逛水果街Ⅱ
- codevs 2370 小机房的树 (LCA)
- 【codevs2370】小机房的树——倍增法/链剖求LCA