bzoj3124
很好的一道treedp,当然也挺烦的
首先不难想到先求出一个直径,然后穷举每条边,看他删除之后直径大小是否会变,变了的话就是必须经过的边
下面我们就要想怎么优化,本人语言表达略差,还是配合程序说吧。
type node=record
point,next:longint;
cost:int64;
end; var f:array[..] of int64;
pr,fr:array[..,..] of longint;
g,h:array[..,..] of int64;
p:array[..] of longint;
edge:array[..] of node;
v:array[..] of boolean;
i,n,len,ans,x,y,z:longint; procedure add(x,y,z:longint);
begin
inc(len);
edge[len].point:=y;
edge[len].cost:=z;
edge[len].next:=p[x];
p[x]:=len;
end; function max(a,b:int64):int64;
begin
if a>b then exit(a) else exit(b);
end; procedure dp(x:longint);
var i,y:longint;
begin
i:=p[x];
v[x]:=true;
while i<>- do
begin
y:=edge[i].point;
if not v[y] then
begin
dp(y);
f[x]:=max(f[x],f[y]); //f[]表示以x为根的子树中最长的路径长
if g[y,]+edge[i].cost>g[x,] then //维护以x为根走到底最长的3条路径(显然不能有两条路径经过同一个孩子)
//这里要维护3条,因为要考虑删边的时候碰巧干掉了其中一条,如果单纯求树的直径的时候只要维护最长和次长即可)
begin
g[x,]:=g[x,];
fr[x,]:=fr[x,];
g[x,]:=g[x,];
fr[x,]:=fr[x,];
g[x,]:=g[y,]+edge[i].cost;
fr[x,]:=y; //从哪转移来的
end
else if (g[y,]+edge[i].cost>g[x,]) then
begin
g[x,]:=g[x,];
fr[x,]:=fr[x,];
g[x,]:=g[y,]+edge[i].cost;
fr[x,]:=y;
end
else if (g[y,]+edge[i].cost>g[x,]) then
begin
g[x,]:=g[y,]+edge[i].cost;
fr[x,]:=y;
end;
if f[y]>h[x,] then //h维护的是以x为根的子树中最长的2条路径(不经过根)
begin
h[x,]:=h[x,];
pr[x,]:=pr[x,];
h[x,]:=f[y];
pr[x,]:=y; //从哪转移来的
end
else if f[y]>h[x,] then
begin
h[x,]:=f[y];
pr[x,]:=y;
end;
end;
i:=edge[i].next;
end;
f[x]:=max(f[x],g[x,]+g[x,]);
end; procedure dfs(x:longint;l,d:int64); //l表示以x为终点且不是起点x的后辈的最长路径,d表示之前搜索到的不经过x的最长路径
var i,y:longint;
l1,l2,l3:int64;
begin
i:=p[x];
v[x]:=true;
while i<>- do
begin
y:=edge[i].point;
if not v[y] then //大批的分类讨论
begin
l1:=f[y];
if y=pr[x,] then l2:=h[x,]
else l2:=h[x,];
l2:=max(l2,d); if y=fr[x,] then l2:=max(l2,g[x,]+g[x,])
else if y=fr[x,] then l2:=max(l2,g[x,]+g[x,])
else l2:=max(l2,g[x,]+g[x,]); if y=fr[x,] then l3:=g[x,]
else l3:=g[x,];
l2:=max(l2,l+l3);
if max(l1,l2)<f[] then inc(ans);
dfs(y,max(l3,l)+edge[i].cost,l2);
end;
i:=edge[i].next;
end;
end; begin
readln(n);
fillchar(p,sizeof(p),);
for i:= to n- do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
dp();
writeln(f[]);
fillchar(v,sizeof(v),false);
ans:=;
dfs(,,);
writeln(ans);
end.
bzoj3124的更多相关文章
- 【bzoj3124】 Sdoi2013—直径
http://www.lydsy.com/JudgeOnline/problem.php?id=3124 (题目链接) 题意 求树的直径以及直径的交. Solution 我的想法超麻烦,经供参考..思 ...
- bzoj3124: [Sdoi2013]直径 树形dp two points
题目链接 bzoj3124: [Sdoi2013]直径 题解 发现所有直径都经过的边 一定在一条直径上,并且是连续的 在一条直径上找这段区间的两个就好了 代码 #include<map> ...
- BZOJ3124 SDOI2013直径
本以为必有高论,结果是个思博题.随便找一条直径,最后答案肯定是这条直径上的连续一段,如果某分支长度等于直径上某端的长度这一端都要被剪掉. #include<iostream> #inclu ...
- 【BZOJ3124】[Sdoi2013]直径 树形DP(不用结论)
[BZOJ3124][Sdoi2013]直径 Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节 ...
- [bzoj3124] [Sdoi2013]直径
看了child学长的题解才知道怎么写TAT http://www.cnblogs.com/ctlchild/p/5160272.html 以前不知道直径都是过重心的..代码改着改着就和标程完全一样了Q ...
- 2018.11.05 bzoj3124: [Sdoi2013]直径(树形dp)
传送门 一道sbsbsb树形dpdpdp 第一问直接求树的直径. 考虑第二问问的边肯定在同一条直径上均是连续的. 因此我们将直径记下来. 然后对于直径上的每一个点,dpdpdp出以这个点为根的子树中不 ...
- bzoj千题计划134:bzoj3124: [Sdoi2013]直径
http://www.lydsy.com/JudgeOnline/problem.php?id=3124 第一问: dfs1.dfs2 dfs2中记录dis[i]表示点i距离最长链左端点的距离 第二问 ...
- [BZOJ3124]直径
Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一 ...
- BZOJ3124 [Sdoi2013]直径 【树的直径】
题目 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一棵树上,任意两个节 ...
随机推荐
- Pagekit安装
Pagekit 是一个模块化,轻量的 CMS 系统,基于现代化的技术,如 Symfony 组件和 Doctrine.它提供了一个很好的平台,用于主题和延伸开发.Pagekit 为您提供了工具来创造美丽 ...
- RMQ问题与ST算法
RMQ(Range Minimum/Maximum Query)问题是求区间最值问题. 对于长度为 n 的数组 A,进行若干次查询,对于区间 [L,R] 返回数组A中下标在 [L,R] 中的最小(大) ...
- 获得Radio选中的后面文本框的值
例如: 选中的radio的值在button中显示 代码如下: <!DOCTYPE html> <html lang="en" xmlns="http:/ ...
- 从腾讯QQ升级游戏之“快速加入游戏”功能的实现缺陷看C/S之间如何正确分配相关协作
转载:http://space.itpub.net/17007506/viewspace-615570 笔者在闲暇时,偶尔会登录腾讯QQGame玩玩升级游戏.这确实是一款非常优秀的软件作品,腾讯的开发 ...
- SQL语句操作文件
-----先开启命令exec sp_configure 'show advanced options', 1; reconfigure; exec sp_configure 'xp_cmdshell' ...
- C#当中的多线程_任务并行库(中)
发现自己有点懒了!也可能是越往后越难了,看书理解起来有点费劲,所以这两天就每天更新一点学习笔记吧. 4.5 将APM模式转化为任务 书上提供的三种方式 方式一: class Program ...
- MYSQL使用指南(下)
在上篇我们讲了登录.增加用户.密码更改等问题.下篇我们来看看MySQL中有关数据库方面的操作.注意:你必须首先登录到MYSQL中,以下操作都是在MYSQL的提示符下进行的,而且每个命令以分号结束. 一 ...
- struts2 标签的使用之一 s:if(遍历中s:if如何用等)
http://blog.csdn.net/chinajust/article/details/3922718
- SQL打印全年日历
数据库环境:SQL SERVER 2008R2 我之前有写过打印本月日历的SQL,里头有详细的说明.具体请参考前面的博文——生成本月日历. 全年日历只是在本月日历的基础上加了月信息,并按月份分组求得. ...
- Bootstrap 3 支持 IE8
Bootstrap 3 支持 IE8 <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries ...