题意简述
有 $n$ 个箱子 $m$ 个球,第 $i$ 个球开始在箱子 $a_i$,你希望把它移到箱子 $b_i$。
但是移动有限制:想要把某个球移动到某个箱子中,该球原先所在的箱子中至少要有两个球;并且,每个球都是易碎的,所以第 $i$ 个球不能移动超过 $c_i$ 次。
请问是否能达成目标,并求出至少要移动多少次球。保证目标状态中任意箱子中都至少有一个球。$1\le n, m, c_i\le 10^5$。
主要思路
首先对于 $a_i \neq b_i$ 的球,移动至少 1 次是不可少的,故先给答案加上这样的球的个数。
不妨把箱子看作点,球 $i$ 看作边 $a_i\rightarrow b_i$。显然,可以在钦定边无向的情况下先把连通块全拆出来。注意到每个点都有入度,故不可能出现树的连通块。
然后就有了三种连通块:
- 只有一个点的自环。
- 单个环。
- 其他连通块。
第 0 类连通块不用操作次数,而第 2 种可以自己构造出每个球只用移动 1 次的合法方案。
于是如果没有第 1 类连通块,此时已经做完了。
发现从第 1 类连通块外移动一个球到块内,之后块内每个球也只用移动 1 次。不妨称此过程为「处理」。
设第 1 类连通块有 $x$ 个。显然将一个块外球移动到块内这 1 步是不可少的,所以也可以先扔到答案里面。
考虑将第 $i$ 个球移出其所在连通块来处理其他连通块:
- 若其在第 2 类连通块内,且 $a_i \neq b_i$,则其最多可处理 $c_i - 1$ 个连通块,不需要额外操作次数。
- 若其在(已处理的)第 1 类连通块内,则其最多可以处理 $c_i - 1$ 个连通块,而处理该连通块的操作次数在上文已经计算,故同样不需要额外操作次数。
- 若其在第 2 类连通块内,且 $a_i = b_i$,则其最多可处理 $c_i - 1$ 个连通块,且由于其本来不必移动,故需要额外操作次数 $1$ 次。
- 若其在第 0 类连通块内,则其最多可处理 $c_i - 2$ 个连通块,且由于其本来不必移动,并且其移动前需要另一球来「处理」,故需要额外操作次数 $2$ 次。
如何保证 $i$ 球能够移动(即能够安排先后顺序使得其移动前所在连通块已经被处理)?只需先取一个第 2 连通块中的球开始移动。
然后显然不需要额外操作次数的都随便拿。于是只剩下额外操作次数为 $1, 2$ 的球,然后排个序 Two Pointers 即可。
除排序外,复杂度 $O(n)$。
参考代码
1 |
|