\(\mathbf{Part. -1}\)
你有注意过 AtCoder 的这个部分吗?
这里的序号,是在考虑了提高任意两个页面间跳转的速度和每个页面不显示太多的选项这两个因素,并精心考虑之后选出来的。在这个问题,你需要在每个页面只有 两个链接 的前提下实现类似的功能。
Snuke 制作了一个有 \(N\) 个页面的网站,分别标号为 \(1\) 到 \(N\) 。对每个 \(i(1\le i \le N)\) ,选出两个正整数 \(a_i\) 和 \(b_i(1\le a_i \le N)\) ,把通往第 \(a_i\) 个页面和通往第 \(b_i\) 个页面的链接加入页面 \(i\) 。这个网站必须满足以下的要求:
- 你必须能够在最多点击 \(10\) 个链接后从任意的一个页面跳转到任意的另一个页面\(^{\color{red}(1)}\)。
在这个问题的限制条件下,我们可以证明这是一定可行的。
\(1 \le N \le 1000\)
\(\mathbf{Part. 0}\)
根据 \(2^{10} = 1024 > 1000\),不难想到这道题目和 \(2\) 有很大关系。
做题的时候,我直接认为,这道题目是二进制题。但实际上,还有一个和 \(2\) 有关的想法:二叉树。
Ad-hoc 题会有很多的尝试,但是每次尝试之后都要总结失败的原因,然后尝试发掘其他思路,不能被一个思路框死。
\(\mathbf{Part. 1}\)
我们先不考虑 \(\color{red}(1)\) 的限制,只是单纯对可能的答案进行观察。如果我们以二叉树的角度进行观察,会发现,\(x\) 连向 \(a_i, b_i\),整体呈现完全二叉树的形式。似乎 \(a_i,b_i\) 在没有 \(\color{red}(1)\) 的限制时不重要。
现在,我们考虑 \(\color{red}(1)\) 的性质,直接做很难做,所以先弱化一下,我们不要求直接找到完美的方法,如果有缺陷,我们可以调整。我们结合二叉树,考虑对 \(a_i, b_i\) 朴素的赋值成 \(2x\) 和 \(2x+1\),那么从任意一个点出发都能走到所有在 \(x\) 子树内的点。
但是,只有一部分的点对能满足要求,其他的都到达不了,于是我们思考哪里还没被充分运用。然后我们发现很唐啊,对于每个叶子节点,我们都没有钦定它的 \(a_i, b_i\),也就是说我们还有接近一半的信息可以构造。
对于叶子节点,最暴力的想法就是将它们的 \(a_i, b_i\) 全部设为 \(1\),也就是根。这样,我们就可以在一个 \(x\) 走到叶子之后,跳回根,这时就能走到所有点了。
\(\mathbf{Part. 2}\)
但是,我们这时候发现假了:这样的话,跳转次数会达到 \(20\) 次左右。那咋办???
其实,对于叶子节点的信息,我们是将他们全部设为 \(1\) 的,这太浪费了。考虑从这个角度继续进行调整。
我们想一个叶子 \(i\) 的 \(a_i\) 和 \(b_i\) 需要满足什么:
- 从 \(i\) 出发,它要到达所有节点,所以显然 \(a_i\) 和 \(b_i\) 需要覆盖整棵树。
- 我们不能太浪费点击次数。