1602: [Usaco2008 Oct]牧场行走(倍增模板)

var
  sum,ee,q,xx,yy,deep,u,c,v,k,i,j,n,m:longint;
  len,p:array[0..100000,0..20]of longint;
  a,next,long,e,head,d,f:array[0..100000]of longint;
function lca(a,b:longint):longint;
  var tt,i,j,k:longint;
  begin
  if d[a]>d[b] then begin tt:=a;a:=b;b:=tt;end;
  k:=trunc(ln(d[b])/ln(2));
  for i:=k downto 0 do
    if d[b]-1 shl i>=d[a] then
      begin
      sum:=sum+len[b,i];
      b:=p[b,i];
 
      end;
  if a=b then exit(a);
  k:=trunc(ln(d[b])/ln(2));
  for i:=k downto 0 do
    if p[a,i]<>p[b,i] then
      begin
      sum:=sum+len[b,i]+len[a,i];
      b:=p[b,i];a:=p[a,i];
      end;
  sum:=sum+len[a,0]+len[b,0];
  exit(f[a]);
end;
procedure add(u,v,c:longint);
  begin
  inc(ee);
  next[ee]:=head[u];
  head[u]:=ee;
  long[ee]:=c;
  e[ee]:=v;
  inc(ee);
  e[ee]:=u;
  next[ee]:=head[v];
  head[v]:=ee;
  long[ee]:=c;
 
  end;
procedure doo;
  var h,t,j:longint;
  begin
  a[1]:=1;h:=1;t:=1;
  while h<=t do
  begin
  j:=head[a[h]];
  while j<>0 do
    begin
    if d[e[j]]=0 then
      begin
      d[e[j]]:=d[a[h]]+1;
      f[e[j]]:=a[h];
      len[e[j],0]:=long[j];
      inc(t);
      a[t]:=e[j];
      end;
    j:=next[j];
    end;
  inc(h);
  end;
end;
 
 
 
begin
  readln(n,m);
  d[1]:=1;
  for i:=1 to n-1 do
    begin
      readln(u,v,c);
    add(u,v,c);
    end;
  doo;
  for i:=1 to n do
    p[i,0]:=f[i];
  for i:=1 to n do
    if d[i]>deep then
      deep:=d[i];
  k:=trunc(ln(deep)/ln(2));
  for j:=1 to k do
    for i:=1 to n do
        begin
      p[i,j]:=p[p[i,j-1],j-1];
      len[i,j]:=len[i,j-1]+len[p[i,j-1],j-1];
      end;
  for i:=1 to m do
    begin
    sum:=0;
      readln(xx,yy);
    lca(xx,yy);
    writeln(sum);
      end;
    end.

 

posted @ 2013-03-01 15:57  lbz007  阅读(210)  评论(0编辑  收藏  举报
Live2D