【SDOI2013】直径 【题目描述】 小 Q最近学习了一些图论知识。根据课本,有如下定义。 树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度。如果一棵树有N个节点,可以证明其有且仅有 N-1 条边。 路径:一棵树上,任意两个节点之间最多有一条简单路径。我们用 dis(a,b)表示点 a 和点 b 的路径上各边长度之和。称 dis(a,b)为 a、b 两个节点间的距离。 直径:一棵树上,最长的路径为树的直径。树的直径可能不是唯一的。 现在小 Q 想知道,对于给定的一棵树,其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。 【输入】 第一行包含一个整数 N,表示节点数。 接下来 N-1行,每行三个整数 a, b, c,表示点 a和点b之间有一条长度为 c的无向边。 【输出】 共两行。第一行一个整数,表示直径的长度。第二行一个整数,表示被所有直径经过的边的数量。 【输入样例】 6 3 1 1000 1 4 10 4 2 100 4 5 50 4 6 100 【输出样例】 1110 2 【数据范围】 对于 20%的测试数据:N≤100 对于 40%的测试数据:N≤1000 对于 70%的测试数据:N≤100000 对于 100%的测试数据:2≤N≤200000,所有点的编号都在 1..N 的范围内,边的权值≤10^9。 【题解】 从某天犇的博客上学到的方法,先OTL五分钟…… 第一问求直径,先随便选择一个节点bfs,然后从这个节点bfs到最远的节点再bfs一次,这次bfs到达的最远的节点和出发点之间一定能够成一条直径。至于原理么,大家还是自行度娘一下啦~\(≧▽≦)/~ 第二问需要保留第一问的直径,然后直径上的节点dfs下去,如果这个节点dfs到某个点的距离和它到直径某一端的距离相等,就说明过这一点一定有另一条直径。这样从两头夹逼至中间,剩下的链就是一定在直径上的部分了。 关于第二问结论的正确性,是因为不存在两条直径没有任何公共点和公共边,否则它们可以构成更长的链。 【代码】 第一问bfs,第二问dfs,时间还不错。 【SDOI2013】直径#代码