AT ARC189E Straight Path
首先发现的是 \(n = 2, 3\) 必定无解。
接下来考虑 \(n\ge 4\) 的情况。
首先手玩一下小数据 \(n = 4\)。
因为此时对应的图为一个带对角线的正方形,于是可以从对称的角度入手,得到 \(\max = 3\) 的解:
\(\begin{matrix}1 & {\color{red}{-}} & 2\\ {\color{blue}{|}} & {\color{green}{\times}} & {\color{blue}{|}} \\ 3 & {\color{red}{-}} & 4\end{matrix}\)
其中三个颜色各代表一种颜色,方便起见,钦定蓝色为 \(1\),红色为 \(2\),绿色为 \(3\)。
首先通过 \(n = 4\) 的手玩,猜测 \(\max = 3\) 为下界,即不存在 \(\max = 1 / 2\)。
对于 \(\max = 1\) 不存在是显然的,因为任意一条路径权值都相同。
还要证明不存在 \(\max = 2\) 的构造。
其实就是要证明不管怎样对边染 \(0 / 1\),都存在 \(0\to 0\to \cdots\to 0\to 1\cdots\to 1\) 这样的哈密顿路径。
对于这种对边有要求的哈密顿路径构造,通常一个比较好用方式的是增量构造。
考虑对于前 \(i\) 个点的路径,如果边权为一个值就直接把 \(i + 1\) 放在后面。
否则找到 \(\cdots \to 0 \to 0 \to 1 \to 1 \to \cdots\) 这个转折点的位置,记 \(w(p_1, u) = 0, w(u, p_2) = 1\)(\(u\) 是 \(0 \to 1\) 分界处的公共点,\(p_1, p_2\) 为 \(u\) 前面 / 后面的一个点)。
考虑分讨 \(w(u, i + 1) = 0 / 1\) 进行构造。
- \(w(u, i + 1) = 0\),对应有构造 \(\cdots \to 0 \to (w(u, i + 1) = 0) \to (w(i + 1, p_2) = 0 / 1) \to 1 \to \cdots\)。
- \(w(u, i + 1) = 1\),对应有构造 \(\cdots \to 0 \to (w(p_1, i + 1) = 0 / 1) \to (w(i + 1, u) = 1) \to 1 \to \cdots\)。
于是可以知道,当 \(\max = 2\) 时一定不存在合法的情况。
于是接下来考虑如何构造出 \(\max = 3\) 的方案。
因为只能有 \(3\) 种边权,于是考虑先类二分图的让一种边权用来区分出几个部分。
构造需要尽量有普适性,于是先只分成两个部分。
考虑如何区分出这两个部分。
一个构造想法就是每一部分内部的边都为 \(1\),而两部分之间的连边都为 \(2, 3\)。
考虑这样连边后,可能不增 / 不减的路径的形态就是:
在一个部分内部先走(也可以不走),剩下的边都是在两个部分内反复跳。(也有可能是反过来,当然情况都一样。)
这是因为如果在两个部分间跳就至少走过了一条 \(2 / 3\),如果前面后面都走过 \(1\) 就不合法了,于是形态一定成这样。
那么进一步思考,如果 \(n\) 为偶数,把两部分分成 \(\frac{n}{2}, \frac{n}{2}\),那么合法的路径一定会是一直在两个块间反复跳。
这是因为对于两个块间跳,经过的点数 \(x, y\)(钦定 \(x\) 为起点所在的块)应该满足 \(y + 1\ge x\ge y\),那么如果先先在块内走了一步两部分点数就变为了 \(\frac{n}{2} - 1, \frac{n}{2}\),那么后面一定还会在另一个块内走,就不合法了。
同理的,如果对于 \(n\) 为奇数的情况,把两部分分为 \(\lfloor\frac{n}{2}\rfloor, \lceil\frac{n}{2}\rceil\)。
那么合法的路径类似上面的分析可以知道是:
从 \(\lceil\frac{n}{2}\rceil\) 的块开始,至多在块内走一步,然后都在两个块内跳。
于是发现一定要满足的是,不存在只在两个块内一直跳的合法路径。(先不考虑 \(n\) 为奇数时另一种情况。)
考虑复用信息,把每部分的点再分成两个部分,对应前面 \(n = 4\) 的构造的左边 / 右边一列的两个点,然后按照 \(n = 4\) 的情况连边权为 \(2, 3\) 的边。
于是 \(n\) 为偶数的情况就解决完了。
但是 \(n\) 为奇数的情况似乎还有问题,比如样例的 \(n = 5\) 对应的 \(\max = 4\)。
那么唯一的问题就出在可能是从 \(\lceil\frac{n}{2}\rceil\) 的块内走了一步再走出来的。
考虑当 \(n = 5\) 时为何存在合法的路径,此时这个块内只有 \(3\) 个点,再次分出的两个部分的点数分别应为 \(1, 2\)。
那么就可以第一步在块内走的时候先把点数为 \(1\) 的部分走掉,那么实际上就是 \(n = 4\) 的情况去掉了一个点,且这一个块内的另一部分点数为 \(2\),那么此时一定存在 \(2 - 2 - 3\) 的路径,而且第一条边边权是 \(1\),于是路径合法。
继续沿用这个分析,考虑当 \(n\ge 7\) 时。
起始块的点数 \(\ge 4\),那么再分出的两个部分的点数肯定都能满足 \(\ge 2\)。
那么此时不管从哪个部分开始走,肯定这个块的两个部分都还会有点。
那么此时 \(n = 4\) 的情况的 \(4\) 个点都还在,就一定就不会存在合法路径了。
于是可以通过分析知道,这个构造只有当 \(n = 5\) 不合法,其他情况下都满足 \(\max = 3\) 且构造合法。
对于 \(n = 5\) 可以直接粘样例。
对于其余构造,更好写的做法是直接让 \(n = 4\) 中的第 \(i\) 个点的点数为 \(\lfloor\frac{n}{4}\rfloor + [n\bmod 4 \ge i]\)(把编号 \(i\) 分到 \((i - 1)\bmod 4 + 1\) 组)。
可以知道这个点数分配满足构造需要的条件。
时间复杂度 \(\mathcal{O}(n^2)\),这个题的数据范围应该是给 checker 开的。
#include<bits/stdc++.h>
constexpr int maxn = 20 + 2;
int a[maxn][maxn];
int main() {
int n;
scanf("%d", &n);
if (n == 2 || n == 3) {
return puts("No"), 0;
}
puts("Yes");
if (n == 5) {
printf("2 1 4 4\n");
printf("4 3 1\n");
printf("1 3\n");
printf("2\n");
return 0;
}
for (int i = 1; i <= n; i++, puts("")) {
for (int j = i + 1; j <= n; j++) {
if ((i & 1) == (j & 1)) printf("1 ");
else if ((i & 2) == (j & 2)) printf("2 ");
else printf("3 ");
}
}
return 0;
}
浙公网安备 33010602011771号