题意:一棵树上石神被两个陌生人跟踪,将三秒看做一个周期,在一个周期内,第一秒石神可以静止或移动到任意相邻节点,后两秒陌生人都朝着石神的方向走到相邻节点,问石神最迟第几秒被追上。
考虑每一个点,如果一个点是一个陌生人会追到石神的点,要么是石神和陌生人在同一周期到达的点,要么是陌生人比石神晚到的叶节点,在这些点中取一个时间最晚的。有个细节是如果石神在某一点被追上了,就不要dfs子树了,否则答案就会更大。
type
edge=record
y,next:longint;
end;
const
MAXN=200050;
var
map:array[0..MAXN*2] of edge;
time:array[1..3,0..MAXN] of longint;
first:array[0..MAXN] of longint;
n,ss,p,q,i,x,y,s,t,ans:longint;
procedure ins(x,y:longint);
begin
inc(s);map[s].y:=y;
map[s].next:=first[x];first[x]:=s;
end;
function min(a,b:longint):longint;
begin if (a<b) then exit(a) else exit(b); end;
function max(a,b:longint):longint;
begin if (a>b) then exit(a) else exit(b); end;
procedure dfs1(x,tm,f:longint);
var
t,new,son,temp:longint;
begin
time[1][x]:=tm;
temp:=min(time[2][x],time[3][x]);
if ((temp-1) div 3+1=(time[1][x]-1) div 3+1)
then begin ans:=max(ans,temp);exit;end;
if (tm=0)
then new:=1
else new:=tm+3;
t:=first[x];son:=0;
while (t>0) do
begin
if (map[t].y<>f)
then begin dfs1(map[t].y,new,x);inc(son);end;
t:=map[t].next;
end;
if (son=0)and(min(time[2][x],time[3][x])>time[1][x])
then ans:=max(ans,min(time[2][x],time[3][x]));
end;
procedure dfs2(x,tm,f:longint);
var
t,new:longint;
begin
time[2][x]:=tm;
new:=tm+1+ord(tm mod 3=0);
t:=first[x];
while (t>0) do
begin
if (map[t].y<>f)
then dfs2(map[t].y,new,x);
t:=map[t].next;
end;
end;
procedure dfs3(x,tm,f:longint);
var
t,new:longint;
begin
time[3][x]:=tm;
new:=tm+1+ord(tm mod 3=0);
t:=first[x];
while (t>0) do
begin
if (map[t].y<>f)
then dfs3(map[t].y,new,x);
t:=map[t].next;
end;
end;
begin
assign(input,'track.in');reset(input);
assign(output,'track.out');rewrite(output);
read(n,ss,p,q);
for i:=1 to n do
begin
read(x,y);
ins(x,y);
ins(y,x);
end;
ans:=0;
dfs2(p,0,0);
dfs3(q,0,0);
dfs1(ss,0,0);
//for i:=1 to n do write(time[1][i],' ');writeln;
//for i:=1 to n do write(time[2][i],' ');writeln;
//for i:=1 to n do write(time[3][i],' ');writeln;
writeln(ans);
close(input);close(output);
end.