Description
YJC最近在学习图的有关知识。今天,他遇到了这么一个概念:随机游走。随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次。YJC很聪明,他很快就学会了怎么跑随机游走。为了检验自己是不是欧洲人,他决定选一棵树,每条边边权为 1 1 ,选一对点 s s 和 t t ,从 s s 开始随机游走,走到t就停下,看看要走多长时间。但是在走了 10000000 10000000 步之后,仍然没有走到 t t。YJC坚信自己是欧洲人,他认为是因为他选的 s s 和 t t 不好,即从 s s 走到 t t 的期望距离太长了。于是他提出了这么一个问题:给一棵 n n 个点的树,问所有点对(i,j)(1≤i,j≤n)(i,j)(1≤i,j≤n)中,从 i i 走到 j j 的期望距离的最大值是多少。YJC发现他不会做了,于是他来问你这个问题的答案。
Input
第一行包含一个整数 n n,表示点数。
接下来 n−1 n−1 行,第 i+1 i+1 行包含两个整数uiui和vivi,表示树的一条边。
Output
输出一行,包含一个实数,表示最大的期望距离,保留五位小数。
Sample Input
3
1 2
2 3
Sample Output
4.00000
Data Constraint
对于30%30%的数据,满足n≤5n≤5。
对于50%50%的数据,满足n≤3000n≤3000。
对于100%100%的数据,满足n≤100000n≤100000。
Hint
s=1,t=3,s=1,t=3,从 11走到距离为11,从走到33的期望距离满足d=0.5(d+2)+0.5d=0.5(d+2)+0.5,解得d=3d=3,所以从11走到的期望距离为44。
Solution
期望题!每次做期望题都没信心。
我们来分析相邻点之间期望值怎么求。
不妨设从到 y y 的期望步数为e[x,y]e[x,y]。
要使当前点到达目标点,会有以下几种可能。
①折返:从WW走到其余点之一,经过一番波折又回到当前点再到目标点
步数{11为从到 x x 的步数},共有KK种这样的可能
②直达:直接从到 P P
步数f=1f=1,共有 1 1 种这样的可能
然而每一种方案概率都是相等的,即可得
e[w,p]=∑ki=1(1+e[xi,w]+e[w,p])+1k+1e[w,p]=∑i=1k(1+e[xi,w]+e[w,p])+1k+1
进一步化简可得
e[w,p]=∑i=1ke[xi,w]+k+1e[w,p]=∑i=1ke[xi,w]+k+1
设 d[x] d[x] 为 x x 的度数,又可化得
e[w,p]=∑i=1ke[xi,w]+d[w]e[w,p]=∑i=1ke[xi,w]+d[w]
所以对于一颗树,∀x,y∀x,y两点期望都有e[x,y]=e[x,w1]+e[w1,w2]+..+e[w2,y]e[x,y]=e[x,w1]+e[w1,w2]+..+e[w2,y]
即路径期望和。
很像什么,e[x,y]e[x,y]就像是树枝的权值!但要注意是有向的,本题要求最大的点对期望距离,那不就相当于树的直径吗?
设 f[i] f[i] 为结点 i i 到其父亲的期望值, g[i] g[i] 为 i i 的父亲到结点 i i 的期望值。
那么根据上述分析就有如下转移:
f[i]=∑y∈son[x]f[y]+d[x]f[i]=∑y∈son[x]f[y]+d[x]
g[i]=∑y∈son[fa[x]]−f[i]+g[fa[x]]+d[fa[x]]g[i]=∑y∈son[fa[x]]−f[i]+g[fa[x]]+d[fa[x]]
设 f2[i] f2[i] 为 i i 结点到其子树叶子最大期望, g2[i] g2[i] 为 i i 子树叶子到 i i 的最大期望。
所以
f2[i]=max(f2[y]+f[y]),y∈son[x]f2[i]=max(f2[y]+f[y]),y∈son[x]
g2[i]=max(g2[y]+g[y]),y∈son[x]g2[i]=max(g2[y]+g[y]),y∈son[x]
设 p[i] p[i] 为以 i i 为根的子树经过 i i 的最大期望步数。
若 i i 的儿子只有一个,则
p[i]=max(g2[i],f2[i])p[i]=max(g2[i],f2[i])
若 i i 的儿子大于一个,那么
p[i]=max(f[y1]+f2[y1]+g[y2]+g2[y2]),y1,y2∈son[x]且y1≠y2p[i]=max(f[y1]+f2[y1]+g[y2]+g2[y2]),y1,y2∈son[x]且y1≠y2
于是ans= max(p[i])ans= max(p[i]),一个树形 DP DP 就搞定了。
Code
const maxn=100005;
var tot,x,y,i,n:longint;
ans:int64;
g,yy,next:array[0..2*maxn] of longint;
s,fa,son,f,f2,l1,l2:array[0..maxn] of int64;
function max(x,y:int64):int64;
begin if x>y then exit(x);exit(y);end;
procedure make(x,y:longint);
begin
inc(tot);
yy[tot]:=y;
next[tot]:=g[x];
g[x]:=tot;
end;
procedure dfs(x:longint);
var i,y:longint;
begin
i:=g[x];
while i<>0 do begin
y:=yy[i];
if fa[x]<>y then begin
fa[y]:=x;
son[y]:=1;
dfs(y);
son[x]:=son[x]+1;
s[x]:=f[y]+s[x];
end;
i:=next[i];
end;
f[x]:=s[x]+son[x];
end;
procedure dfs2(x:longint);
var a1,a2,b1,b2,i,y:longint;
begin
i:=g[x];
if x<>1 then
f2[x]:=s[fa[x]]-f[x]+f2[fa[x]]+son[fa[x]];
a1:=0;a2:=0;
b1:=0;b2:=0;
while i<>0 do begin
y:=yy[i];
if fa[x]<>y then begin
dfs2(y);
if l1[y]+f[y]>f[a1]+l1[a1] then begin
a2:=a1;
a1:=y;
end else if f[y]+l1[y]>f[a2]+l1[a2] then a2:=y;
if f2[y]+l2[y]>f2[b1]+l2[b1] then begin
b2:=b1;
b1:=y;
end else if f2[y]+l2[y]>f2[b2]+l2[b2] then b2:=y;
end;
i:=next[i];
end;
l1[x]:=l1[a1]+f[a1];
l2[x]:=l2[b1]+f2[b1];
if (son[x]=1) or ((son[x]=2) and (x<>1)) then ans:=max(max(ans,l1[x]),l2[x]) else
if a1<>b1 then ans:=max(ans,l1[x]+l2[x]) else begin
ans:=max(ans,f[a1]+l1[a1]+f2[b2]+l2[b2]);
ans:=max(ans,f[a2]+l1[a2]+f2[b1]+l2[b1]);
end;
end;
begin
assign(input,'rw.in');reset(input);
assign(output,'rw.out');rewrite(output);
readln(n);
for i:=1 to n-1 do begin
readln(x,y);
make(x,y);
make(y,x);
end;
dfs(1);
dfs2(1);
writeln(ans,'.00000');
close(input);
close(output);
end.