题意简述:给出一个
n
个点的树(有边权),问删除其中一条边,剩下最长链的长度的期望。(乘(n−1)输出)
题解:经典树形dp,用down1、down2、down3记录每个点向下的第一第二第三长链,up记录每个点向上最长链,son1、son2记录每个点有第一第二长链的两棵子树,dis记每个点到其父亲的边权,down_ans记录每个点向下的答案,lws是longest_without_subtree,是动态修改的,lws[x]记录对于枚举的当前x的一个儿子y,不包含y这棵子树的最长路。对于一个点,只要down_ans和lws取个max即可。
代码丑,不要看。。
type
edge=record
y,v,next:longint;
end;
rec=record
x:longint;
v:int64;
end;
const
MAXN=500050;
var
map:array[0..MAXN * 2] of edge;
down1,down2,down3,son1,son2:array[0..MAXN] of rec;
down_ans,up,lws:array[0..MAXN] of int64;
first,dis:array[0..MAXN] of longint;
s:longint;
ans:int64;
function max(a,b:int64):int64;
begin if (a>b) then exit(a) else exit(b); end;
procedure swap(var a,b:int64);
var t:int64;
begin t:=a;a:=b;b:=t; end;
procedure ins(x,y,v:longint);
begin
inc(s);map[s].y:=y;map[s].v:=v;
map[s].next:=first[x];first[x]:=s;
end;
procedure init;
var
n,i,x,y,v:longint;
begin
read(n);ans:=0;
for i:=1 to n-1 do
begin
read(x,y,v);
ins(x,y,v);
ins(y,x,v);
end;
end;
procedure dfs1(x,f:longint);
var
t,y,v:longint;
begin
t:=first[x];
while (t>0) do
begin
y:=map[t].y;v:=map[t].v;
if (y<>f) then
begin
dfs1(y,x);dis[y]:=map[t].v;
if (down1[y].v+v>=down1[x].v)
then
begin
down3[x]:=down2[x];
down2[x]:=down1[x];
down1[x].x:=y;
down1[x].v:=down1[y].v+v;
end
else
if (down1[y].v+v>=down2[x].v)
then
begin
down3[x]:=down2[x];
down2[x].x:=y;
down2[x].v:=down1[y].v+v;
end
else
if (down1[y].v+v>down3[x].v) then
begin
down3[x].x:=y;
down3[x].v:=down1[y].v+v;
end;
if (down_ans[y]>=son1[x].v)
then
begin
son2[x]:=son1[x];
son1[x].x:=y;
son1[x].v:=down_ans[y];
end
else
if (down_ans[y]>son2[x].v) then
begin
son2[x].x:=y;
son2[x].v:=down_ans[y];
end;
down_ans[x]:=max(down_ans[x],down_ans[y]);
end;
t:=map[t].next;
end;
down_ans[x]:=max(down_ans[x],down1[x].v+down2[x].v);
end;
procedure dfs2(x,f:longint);
var
t:longint;
begin
t:=first[x];
if (x=1)
then up[x]:=0
else
begin
if (down1[f].x=x)
then up[x]:=down2[f].v
else up[x]:=down1[f].v;
up[x]:=max(up[x],up[f]);
inc(up[x],dis[x]);
end;
while (t>0) do
begin
if (map[t].y<>f)
then dfs2(map[t].y,x);
t:=map[t].next;
end;
end;
procedure dfs3(x,f:longint);
var
t,y:longint;
t1,t2,t3:int64;
begin
t:=first[x];
if (x<>1) then ans:=ans+max(down_ans[x],lws[f]);
while (t>0) do
begin
y:=map[t].y;
if (y<>f) then
begin
if (down1[x].x=y)
then begin t1:=down2[x].v;t2:=down3[x].v;end
else if (down2[x].x=y)
then begin t1:=down1[x].v;t2:=down3[x].v;end
else begin t1:=down1[x].v;t2:=down2[x].v;end;
t3:=up[x];
if (t1<t3) then swap(t1,t3);
if (t2<t3) then swap(t2,t3);
if (son1[x].x=y)
then lws[x]:=max(son2[x].v,lws[f])
else lws[x]:=max(son1[x].v,lws[f]);
lws[x]:=max(lws[x],t1+t2);
dfs3(y,x);
end;
t:=map[t].next;
end;
end;
begin
assign(input,'split.in');reset(input);
assign(output,'split.out');rewrite(output);
init;
dfs1(1,0);
dfs2(1,0);
dfs3(1,0);
writeln(ans);
close(input);close(output);
end.