[CodeVS1036] 商务旅行

传送门

http://codevs.cn/problem/1036/

题目大意

题解

lca裸题

const
 maxn=30005;
var
 st:array[0..maxn,0..20]of longint;
 w:array[0..4*maxn,1..2]of longint;
 dep,t:array[0..maxn]of longint;
 i,j,k:longint;
 n,m,len,a,b,head,tail,tt,v,maxd,ans:longint;
procedure init(a,b:longint);
begin
 w[len,1]:=b;
 if w[a,2]=0
 then w[a,2]:=len else w[w[a,1],2]:=len;
 w[a,1]:=len; inc(len);
end;

function lca(a,b:longint):longint;
var i:longint;
begin
 if dep[a]>dep[b] then begin i:=a; a:=b; b:=i; end;
 for i:=trunc(ln(maxd)/ln(2)) downto 0 do
  if dep[st[b,i]]>=dep[a] then b:=st[b,i];
 if a=b then exit(a);
 for i:=trunc(ln(maxd)/ln(2)) downto 0 do
  if st[a,i]<>st[b,i]
  then begin a:=st[a,i]; b:=st[b,i]; end;
 exit(st[a,0]);
end;

begin
 readln(n); len:=n+1;
 for i:=1 to n-1 do
  begin readln(a,b); init(a,b); init(b,a); end;
 t[1]:=1; head:=1; tail:=2; dep[1]:=1; maxd:=1;
 while head<tail do
  begin
   v:=t[head]; inc(head); tt:=w[v,2];
   while tt<>0 do
    begin
     if dep[w[tt,1]]=0 then begin
      dep[w[tt,1]]:=dep[v]+1;
      t[tail]:=w[tt,1]; inc(tail);
      st[w[tt,1],0]:=v; if dep[v]+1>maxd then maxd:=dep[v]+1;
     end;
     tt:=w[tt,2];
    end;
  end;
 for j:=1 to trunc(ln(maxd)/ln(2)) do
  for i:=1 to n do
   st[i,j]:=st[st[i,j-1],j-1];
 readln(m); v:=1; ans:=0;
 for i:=1 to m do
  begin
   readln(a);
   inc(ans,dep[a]+dep[v]-2*dep[lca(v,a)]);
   v:=a;
  end;
 writeln(ans);
end.

你可能感兴趣的:([CodeVS1036] 商务旅行)