您的位置:首页 > 其它

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lca 模板 倍增