luogu P10062 [SNOI2024] 拉丁方
首先需要一些前置知识:
每个点都恰好有 \(k\) 个度数的二分图称为 \(k\) 正则二分图,\(k\) 正则二分图一定有完美匹配。
Proof
考虑 Hall 定理,不存在完美匹配当且仅当存在一个左部点的集合 $S$ 使得 $|tr(S)|<|S|$,这意味着 $tr(S)$ 的度数之和要大于等于 $|S|$ 的度数之和,但是因为每个点都恰好有 $k$ 个度数,所以是矛盾的。对于一个 \(k\) 正则二分图,以下求完美匹配算法的时间复杂度是期望 \(O(n\log n)\) 的:
随机一个未匹配的左部点,随机一个有边相连的右部点走过去,如果这个右部点没有匹配就找到一条增广路,否则走匹配边继续走到左部点。找到增广路之后去掉环更新匹配,重复 \(n\) 次。
具体证明不细表,感性理解是在已经匹配 \(t\) 个后期望走 \(O(\frac{n}{n-t})\) 个点就能找到一个未匹配的右部点。运行 \(n\) 次即可在 \(O(n^2\log n)\) 复杂度内找到一个二分图边染色。
当 \(k\) 是偶数的时候,可以跑一遍欧拉回路,然后将欧拉回路相邻两条边划分到不同的子图,这样会分成两个 \(\frac{k}{2}\) 正则二分图。因此,当 \(k=2^t\) 的时候可以 \(O(m)\) 求出一组完美匹配,\(O(m\log k)\) 求出所有完美匹配。
这也就给出了一个确定性找到一组完美匹配的做法:令 \(2^t\) 为最小的 \(\geq m\) 的二进制幂,我们将整张图补成一个 \(2^t\) 正则二分图:令 \(a=\lfloor\frac{2^t}{k}\rfloor,b=2^t-ak\),则将原图的边重复 \(a\) 次,再随便找一个不一定要求是原图的完美匹配重复 \(b\) 次。在这张图上跑 \(t\) 次欧拉回路,每次保留两个子图中不是原图的边更少的一个。因为不是原图的边最多有 \(bn\) 条,而 \(bn<kn=m\leq 2^t\),因此 \(t\) 次之后一定不存在不是原图的边,也就找到了一个完美匹配。这个做法的复杂度是 \(O(m)\) 的。
有了这些前置知识,先考虑 \(C=n\) 的情况,发现这种情况一定有解。具体的,建立一个二分图,左边是列,右边是值,每个列向还没有在这个列上存在的值连边,每次跑一个完美匹配出来就是新增了一行。
然后我们现在只需要将 \(R\times C\) 补齐 到 \(R\times n\),但是现在可能会有无解的情况。假设一种值 \(i\) 还需要出现 \(c_i\) 次,若 \(c_i>n-C\),则显然无解。否则,建立一个二分图,左边是前 \(R\) 行,右边是值,每行向每个没有出现过的值连边。
但是现在有个问题,这个二分图并不是正则二分图,为此,我们给左边补上 \(n-R\) 个虚点,每个点向右边连 \(n-C\) 条边将右边所有点补齐成 \(n-C\) 的度数,然后跑二分图边染色即可。
时间复杂度 \(O(Tn^2\log n)\)。