noip2015 运输计划
题目背景
公元 2044 年,人类进入了宇宙纪元。题目描述
L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条
航道连通了 L 国的所有星球。
小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物
流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道 是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之 间不会产生任何干扰。
为了鼓励科技创新,L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小 P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。
在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后, 这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的 物流公司的阶段性工作就完成了。
如果小 P 可以自由选择将哪一条航道改造成虫洞,试求出小 P 的物流公司完成阶段 性工作所需要的最短时间是多少?
输入输出格式
输入格式:
输入文件名为 transport.in。
第一行包括两个正整数 n、m,表示 L 国中星球的数量及小 P 公司预接的运输计划的
数量,星球从 1 到 n 编号。
接下来 n-1 行描述航道的建设情况,其中第 i 行包含三个整数 ai, bi 和 ti,表示第
i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。 接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个
运输计划是从 uj 号星球飞往 vj 号星球。
输出格式:
输出文件名为 transport.out。
共 1 行,包含 1 个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。
输入输出样例
6 3 1 2 3 1 6 4 3 1 7 4 3 6 3 5 5 3 6 2 5 4 5
11
说明
所有测试数据的范围和特点如下表所示
请注意常数因子带来的程序效率上的影响。
分析:注意到m个计划是同时进行的,那么就是求最大值中的最小值,很明显,二分.二分一个答案m,因为我们二分的是最小值,那么大于m的一定不满足要求,我们把这些路径提出来,要使这些路径都满足要求,而虫洞只能建一个,所以虫洞要建在这些路径的交上,也就是一条边是这些不满足要求的路径的公共边.
那么问题就是怎么求交?先把问题转换一下,如果是在一个序列上求m个区间的交该怎么求?这个交的左边一定有m-1个左端点,加上自己的左端点之后共有m个左端点,那么思路就出来了,给每个左端点赋值为1,然后利用前缀和,看哪个区间的端点的值为m,但是加了1之后是必须要减的,不然在这个交的后面可能还会出现交.实际上就是一个值转移的过程,用左端点的值来覆盖整个区间的值.那么转移到树上该怎么做呢?
一样的,把边的值给深度更大的点(防止叶子节点漏算),那么假设边的左节点为u,右节点为v,那么cnt[u]++,cnt[v]++,cnt[lca(u,v)]-=2,相当于吃了就必须给我吐出来.那么cnt[u] += ∑cut[son[u]],实际上就对应了区间上的前缀和.
然后的问题就是怎么求lca,方法有很多,倍增,tarjan,树剖......树剖的预处理比较麻烦,但是很好写.然后就是怎么计算两个点之间的距离,这个可以在预处理的时候解决,计算每个点到根节点的距离d,然后假设一条边的左端点为u,右端点为v,那么dist = d[u] + d[v] - 2*d[lca(u,v)],反正要记住一点,树上求路径要想起lca.
但是即使是这样还是不能A这道题,会TLE一个点,因为常数因子会对算法效率带来影响,然后我就不知道怎么办了......一般在赛场上不会为了5分去想很长时间,除非很关键.