这道题是一道不错的图论题。其题意是这样的,在给出的一棵无根树中,拆掉其中的一条边(此时原图会变成两棵树),然后保持这条边的长度不变,用这条边将两棵树连接起来。(似乎拆掉之后,如果有必要,还可以连回原来的地方)。然后找到一种拆法,使得进行完这个过程后,整棵树的直径是最短的。题目求的就是这最短的直径是多少。

一开始不太有思路,后来 Google 到一篇文章,大致说了一下这道题和树的直径和半径有关,并且是枚举那条要拆的边。[ALP'10]

然后终于想通:拆掉一条边,之后分别求产生的两棵树的直径、中心和半径。再将两棵树的中心以刚才被拆的边相连,得到的结果就是拆这条边能够得到的最优解。假设拆掉的边的长度为 L, 那两棵树的直径和半径分别为 D1, D2, R1, R2, 那么,得到的结果这棵树的直径是 max{D1, D2, R1 + R2 + L}.

这道题的数据规模比较大,有 10 个 cases, 每个 case 至多能有 2500 个节点。使用这种方法似乎复杂度有 O(n2) 之大,我自己写了一个数据生成器,测试了最极端的数据,也到了将近 30 秒才出解。但是我提交到了 OJ 上,还是过了。可能数据没有想象的那么夸张吧。

本题源代码

自己写的极端数据生成器

参考

原创文章,转载请注明来源:http://euyuil.com/3114/acm-icpc-2010-tianjin-building-roads-solution/