NOIP2015运输计划的一个O(n)解法
一个O(n)的解法。 不难发现有如下性质: 被改造成虫洞的边一定在最长路径上 那么,我们用类似提直径的方法把 这条路径给拎出来 就会形成这样的一棵树。 那么,对于一条边,若其被改成虫洞,最长路径会有如下三种情况: 依然是当前的最长路径 被改造边左端点的最长路径 被改造边右端点的最长路径 难道我们不用考虑经过该边的路径吗?? 当然不用。 我们已经是在 最长路径 上改造边了, 而最长路径是长于任何一条路径的 (废话),那么经过该边的任何路径在此边被改造后 依然短于最长路径 ,故不用考虑。 至于求两端的最长路径,我们可以前缀和后缀分别维护一下。 那么怎么求前缀(后缀)呢? 我们可以在每个点开个vector,对于一条路径,我们把另一端点以及路径的编号加到vector中。 然后,再开个vis数组,表示这个点是否被访问过。 在遍历时,我们访问所有以这一点为一端点的路径标号 \(id\) 和另一端点 \(y\) ,若另 \(vis[y]=true\) ,就拿 \(id\) 的长度去更新即可。(口胡不清,这最好手动模拟一下) 至于求路径长和LCA呢? 额,树剖我是当常数看的。。。 实在不行你可以Tarjan离线预处理啊 代码( 巨丑无比 ): #include<bits/stdc++.h> #define reg register int #define MAXN 300010 using