赛时怎么连这题都不会。再不练练思维真的就连普及题都不会做了啊。
Solution
题目来源:ABC338D(in Atcoder | in 洛谷)。
不妨先考虑应该断掉哪条边。首先我们发现,仅断掉一条边并不会让两个结点不可达,只会让我们从一个结点绕更远的路到达目标结点。
如果我们要从结点 \(u\) 前往结点 \(v\)(假设 \(u < v\)),无非就两条路径(重复走过某条边无意义):沿着 \(u\) 走过若干个 \(\ge u\) 且 \(\le v\) 的结点;从 \(u\) 走到 \(1\),绕到 \(n\) 再走到 \(u\)。这两条路径经过的边数都很好算。前者为 \((v - u)\) 条,后者为 \([(u - 1) + (n - v) + 1] = (u + n - v)\) 条。
记两路径的边数差为 \(r = \left | (v - u) - (u + n - v) \right | = \left | -2u + 2v - n \right |\)。我们钦定走边数少的路径,如果断掉该路径上的任意一条边,我们都会绕另一条路,多走 \(r\) 条边。所以我们可以认为 该路径上的边被断掉的代价为 \(r\)。那么对于每组路径要求,我们可以直接离线地在环上差分,让该路径上所有边代价整体 \(+ r\),再在最后用前缀和求出每条边被断掉的总代价。
最后只需断掉总代价最小的边即可。答案即为 所走过的最短路径之和 加上 最小代价 \(r_\min\)。
断环为链地实现差分和前缀和即可。实现时注意以下几点:
- 开
long long
。打擂台取 \(\min\) 时上界不要开小。 - 不要混淆边的编号和点的编号。