WikiOI 2370 小機房的樹 (最裸LCA)

2021-07-24 08:06:40 字數 2814 閱讀 2446

2370 小機房的樹

時間限制: 1 s

空間限制: 256000 kb

題目等級 : 鑽石 diamond

題解 題目描述 description

小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n-1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩隻蟲子,他們不想花費太多精力。已知從某個節點爬到其父親節點要花費 c 的能量(從父親節點爬到此節點也相同),他們想找出一條花費精力最短的路,以使得搞基的時候精力旺盛,他們找到你要你設計乙個程式來找到這條路,要求你告訴他們最少需要花費多少精力

輸入描述 input description

第一行乙個n,接下來n-1行每一行有三個整數u,v, c 。表示節點 u 爬到節點 v 需要花費 c 的精力。

第n+1行有乙個整數m表示有m次詢問。接下來m行每一行有兩個整數 u ,v 表示兩隻蟲子所在的節點

輸出描述 output description

一共有m行,每一行乙個整數,表示對於該次詢問所得出的最短距離。

樣例輸入 sample input

31 0 1

2 0 1

1 02 0

1 2樣例輸出 sample output

1資料範圍及提示 data size & hint

1<=n<=50000, 1<=m<=75000, 0<=c<=1000

學lca之後寫的第一道練習題,很裸,但是很基礎,很多後來寫的lca也是從這一題的**演變出來的。

program mys;

type ab=^node;

node=record

data,ends:longint;

next:ab;

end;

var x,y,z,u,v,i,j,k,m,n:longint;

f,d,c:array[0..50000]of longint;

dp:array[0..50000,0..30] of longint;

b:array[0..50000]of boolean;

p,a,pa,pp:array[0..50000]of ab;

procedure

add(x,y,z:longint);

var i:ab;

begin

i:=p[x];

new(p[x]);

p[x]^.data:=z;

p[x]^.ends:=y;

p[x]^.next:=i;

end;

procedure

dfs(x:longint);

var i:ab;

y:longint;

begin

b[x]:=true;

i:=p[x];

while i<>nil

dobegin

if b[i^.ends]=false

then

begin

f[i^.ends]:=x;

d[i^.ends]:=d[x]+1;

c[i^.ends]:=c[x]+i^.data;

dfs(i^.ends);

end;

i:=i^.next;

end;

b[x]:=false;

end;

function

lca(u,v:longint):longint;

var i:longint;

begin

if d[u]then

begin

i:=u;

u:=v;

v:=i;

end;

i:=30;

while d[u]>d[v] do

begin

while d[dp[u,i]]do dec(i);

u:=dp[u,i];

end;

if u=v then

exit(u);

i:=30;

while i>=0

dobegin

while (i>=0) and(dp[u,i]=dp[v,i]) do dec(i);

if i>=0

then

begin

u:=dp[u,i];

v:=dp[v,i];

end;

end;

exit(f[u]);

end;

begin

readln(n);

fillchar(f,sizeof(f),0);

for i:=1

to n do

f[i-1]:=i-1;

for i:=1

to n-1

dobegin

readln(u,v,z);

add(u,v,z);

add(v,u,z);

end;

dfs(0);

for i:=1

to n do

dp[i-1,0]:=f[i-1];

for j:=1

to30

dofor i:=1

to n do

dp[i-1,j]:=dp[dp[i-1,j-1],j-1];

readln(m);

for i:=1

to m do

begin

readln(x,y);

z:=lca(x,y);

writeln(c[x]+c[y]-2*c[z]);

end;

end.

2370 小機房的樹

時間限制 1 s 空間限制 256000 kb 題目等級 鑽石 diamond 小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n 1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩隻蟲子,他們不想花費太多精力。已知從某個節點爬到其父親節點要花...

2370 小機房的樹,lca

小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n 1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩隻蟲子,他們不想花費太多精力。已知從某個節點爬到其父親節點要花費 c 的能量 從父親節點爬到此節點也相同 他們想找出一條花費精力最短的路,以使...

Codevs 2370 小機房的樹

2370 小機房的樹 時間限制 1 s 空間限制 256000 kb 題目等級 鑽石 diamond 傳送門題目描述 description 小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n 1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩...