某首都城市的商人要經常到各城鎮去做生意,他們按自己的路線去做,目的是為了更好的節約時間。
假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,從首都出發能到達任意乙個城鎮,並且公路網路不會存在環。
你的任務是幫助該商人計算一下他的最短旅行時間。
輸入檔案中的第一行有乙個整數
n ,
1<=
n<=
30000
,為城鎮的數目。下面n−
1 行,每行由兩個整數
a 和b(
1≤a,
b≤n;
a≠b)
組成,表示城鎮
a 和城鎮
b有公路連線。在第n+
1 行為乙個整數
m ,下面的
m行,每行有該商人需要順次經過的各城鎮編號。
在輸出檔案中輸出該商人旅行的最短時間。
5
1 21 5
3 54 541
325
7
題意很清楚,求起點至終點每兩個點的最短路徑之和,而這個圖退化成了一棵樹,我們可以想到求出兩點的lc
a 再進行根據深度計算。具體來說,在以t為根的樹中,對於兩點
u ,v,
lca(
t,u,
v)=p
,則di
st(u
,v)=
dep(
u)+d
ep(v
)−2∗
dep(
p)。
參考**如下:
type struct = record
go,next:longint;
end;
var n,m,ans,cnt,cntr:longint;
a:array[0..60200] of struct; //儲存邊
en,enr,father,depth:array[0..30100] of longint;
visited:array[0..30100] of boolean; //儲存訪問記錄
road:array[0..30100] of struct; //儲存詢問
procedure
addedge
(u,v:longint);
//增加一條邊
begin
inc(cnt); a[cnt].go:=v; a[cnt].next:=en[u]; en[u]:=cnt;
end;
procedure
addroad
(u,v:longint);
//增加乙個詢問
begin
inc(cntr); road[cntr].go:=v; road[cntr].next:=enr[u]; enr[u]:=cntr;
end;
procedure
init;
//讀入邊
var i,x,y:longint;
begin
readln(n);
fillchar(a,sizeof(a),0);
for i:=1
to n-1
dobegin
readln(x,y); addedge(x,y); addedge(y,x);
end;
end;
function
getfather
(x:longint):longint;
begin
if father[x]<>x then father[x]:=getfather(father[x]);
exit(father[x]);
end;
procedure
tarjan
(x,fa:longint);
//樸素tarjan演算法
var i,tmp,t1,t2,t3:longint;
begin
father[x]:=x;
i:=en[x];
while (i<>0) do
begin
tmp:=a[i].go;
i:=a[i].next;
if tmp=fa then
continue;
tarjan(tmp,x);
father[tmp]:=x;
end;
visited[x]:=true;
i:=enr[x];
while (i<>0) do
begin
tmp:=road[i].go;
i:=road[i].next;
if visited[tmp] then
begin
t1:=getfather(tmp);
inc(ans,depth[x]+depth[tmp]-2*depth[t1]);
end;
end;
end;
procedure
calcdep
(x,fa:longint);
//計算每個點深度(單獨計算可提高速度)
var i,tmp:longint;
begin
i:=en[x];
while (i<>0) do
begin
tmp:=a[i].go;
i:=a[i].next;
if tmp=fa then
continue;
depth[tmp]:=depth[x]+1;
calcdep(tmp,x);
end;
end;
procedure
main;
//讀取詢問並計算
var i,t,k:longint;
begin
readln(m); readln(t);
for i:=2
to m do
begin
readln(k);
addroad(t,k); addroad(k,t);
t:=k;
end;
fillchar(visited,sizeof(visited),false);
depth[1]:=1;
calcdep(1,1);
tarjan(1,1);
writeln(ans);
end;
begin
init;
main;
end.
Codevs 1036 商務旅行
1036 商務旅行 時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 傳送門題目描述 description 某首都城市的商人要經常到各城鎮去做生意,他們按自己的路線去做,目的是為了更好的節約時間。假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線...
Codevs 1036 商務旅行
時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 題目描述 假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,從首都出發能到達任意乙個城鎮,並且公路網路不會存在環。...
Codevs 1036 商務旅行
時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 題目描述 假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,從首都出發能到達任意乙個城鎮,並且公路網路不會存在環。...