日常训练 20161102 隔离区
来源:互联网 发布:蒙文软件下载手机软件 编辑:程序博客网 时间:2024/06/06 18:08
题意简述:给出一个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.
0 0
- 日常训练 20161102 隔离区
- HEU日常训练10.02
- 日常训练小结
- 日常训练20161012 道路网
- 日常训练20161012 醉酒
- 日常训练20161014 跟踪
- 日常训练20161018 证据
- 日常训练20161018 subset
- 日常训练 平均数
- 日常训练 水箱
- 日常训练 棋盘游走
- 日常训练 20170531 数字
- 日常训练 20170531 探险
- 日常训练 20170531 矩阵
- 日常训练 20170602 Book
- 日常训练 20170602 Equation
- 日常训练 20170603 棋盘
- 日常训练 20170605 EasyProblem
- 【OpenCV】EmguCV颜色识别案例
- OKhttp源码解析---拦截器之CacheInterceptor
- 微信小程序开发入门
- 第十周--项目3-利用二叉树遍历思想解决问题
- 51nod-1278 相离的圆
- 日常训练 20161102 隔离区
- [LeetCode]Search a 2D Matrix
- Android开发-DesignDemo-AndroidStudio(四)单选、子菜单、header
- cpp的杂项
- 二维数组的传递方式
- VCC,VDD,VEE,VSS很头痛吧?这里秒懂!
- 运行错误:java.lang.NoSuchMethodError: No static method setOnApplyWindowInsetsListener
- Process.waitFor()
- git基础:1.创建版本库和版本回退