商務旅行
time limit:11000ms memory limit:65536k
total submit:79 accepted:43
case time limit:1000ms
description
某首都城市的商人要經常到各城鎮去做生意,他們按自己的路線去做,目的是為了更好的節約時間。
假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,從首都出發能到達任意乙個城鎮,並且公路網路不會存在環。
你的任務是幫助該商人計算一下他的最短旅行時間。
input
輸入檔案kom.in中的第一行有乙個整數n,1<=n<=30 000,為城鎮的數目。下面n-1行,每行由兩個整數a 和b (1<=a, b<=n; a<>b)組成,表示城鎮a和城鎮b有公路連線。在第n+1行為乙個整數m,下面的m行,每行有該商人需要順次經過的各城鎮編號。
output
在輸出檔案kom.out中輸出該商人旅行的最短時間。
分析:先建一棵樹,dfs求出每個點的深度,f[i,j]表示點i向上2^j的點,然後lca求最近公共祖先,i,j之間的距離就是deep[i]+deep[j]-deep[lca(i,j)]*2。
**
const
maxn=1000000;
vardeep,ls,next,a,x:array[0..maxn] of longint;
f:array[0..maxn,0..20] of longint;
i,j,n,m,sum,ans,p,q:longint;
procedure init(i,j:longint);
begin
inc(sum);
x[sum]:=j;
next[sum]:=ls[i];
ls[i]:=sum;
end;
procedure dfs(p,q:longint);
vart:longint;
begin
f[p,0]:=q;
deep[p]:=deep[q]+1;
t:=ls[p];
while t>0 do
begin
if x[t]<>q then dfs(x[t],p);
t:=next[t];
end;
end;
function lca(p,q:longint):longint;
vartmp,i,j:longint;
begin
if deep[p]=deep[q]
then p:=f[p,j];
if p=q then exit(p);
for j:=20 downto 0 do
if f[p,j]<>f[q,j] then
begin
p:=f[p,j];
q:=f[q,j];
end;
exit(f[p,0]);
end;
begin
readln(n);
for i:=1 to n-1 do
begin
readln(p,q);
init(p,q);
init(q,p);
end;
deep[0]:=-1;
dfs(1,0);
for j:=1 to 20 do
for i:=1 to n do
f[i,j]:=f[f[i,j-1],j-1];
readln(m);
p:=1;
for i:=1 to m do
begin
readln(q);
ans:=ans+deep[p]+deep[q]-(deep[lca(p,q)]*2);
p:=q;
end;
writeln(ans);
end.
LCA SSL 1746 商務旅行
第一次用倍增做lc a lca 給定乙個 n n 個點,n 1 role presentation style position relative n 1 n 1條邊的五項圖,給定 m m 個點,求走完它們所有點的長度 乍看似乎是搜尋,然而絕對超時,正解是用lc a role presentatio...
1036 商務旅行 lca 離線
題目描述 description 某首都城市的商人要經常到各城鎮去做生意,他們按自己的路線去做,目的是為了更好的節約時間。假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,從首都出發能到達任意乙...
Codevs P1036 商務旅行 LCA
題目描述 description 某首都城市的商人要經常到各城鎮去做生意,他們按自己的路線去做,目的是為了更好的節約時間。假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,從首都出發能到達任意乙...