[CF869D] The Overdosing Ubiquity 题解
一道非常妙的搜索题,我们可以试着一步一步推到答案。
首先我们思考答案数的上限,假如原图就是一棵树,那么答案总数就是 \(n^2\),因为任意两点之间都有且仅有一条路径,那么考虑再加上一些新边后的路径数会产生什么变化,发现新产生的路径肯定是经过这些新边的,我们可以枚举走哪些边、走的顺序和方向,总体算起来答案最对就是 \(\mathcal O\left(n^22^mm!\right)\),发现因为 \(m\) 非常小,所以后面几乎可以看做是个大常数。
那么问题就变成了点实在太多了,我们很自然地想到要把点删去很多,我们又可以发现这棵树中虽然点很多,但是因为加上去的边非常少,所以有许多的点应当是相似的,实际上设作为新加边端点的点为特殊点,则任意一条路径都可以看成从起点先走到路径上的第一个特殊点,再走到路径上的最后一个特殊点(可能是同一个点),然后再走到终点,而前面和后面的路径是唯一的,也就是说所有任意两点之间如果有多条路径则分叉一定产生在两个特殊点之间。
那么我们可以将所有特殊点之间的路径上的点都取出来构成一张生成图,这样的话剩余的所有点能够到达的第一个生成图中的点一定是唯一的,即将生成图上的点在原图中标出,原图中的每一个点在不经过一个别的标出点的情况下只能走到一个标出点,那么我们对每个标出点进行统计走到它的原图点的个数,介于这张图的特殊性,这里所有标出点一定被所有特殊点及它到根的路径包含,我们可以直接将所有特殊点到根的所有点都加入标记点,这样的好处是虽然并不是所有点都是标记点,应当被标记的点一定全部被包含在内,且方便处理,同时因为每个标出点的父亲也是标出点,那么我们需要统计的实际上就是它的子树大小,可以通过完全二叉树的性质直接统计,同时如果它的儿子是标出点,那么要将儿子的子树减去。
具体代码实现上难度不大,细节也还不多。