不确定是否有更好的方法来处理这个几乎重复的 GCJ - Hamiltonian Cycles,但这是我的答案:
基于 O(2k) 的解决方案使用 inclusion-exclusion principle。鉴于存在 k 个禁止边,则这些边有 2k 个子集边,包括集合本身和空集。例如,如果有 3 个禁止边:{A, B, C},则将有 23=8 个子集:{}、{A}、{B}、{C}、{ A,B}, {A,C}, {B,C}, {A,B,C}。
对于每个子集,您计算至少包括该子集中所有边的循环数。如果包含边 s 的循环数是 f(s) 和 S是所有禁止边的集合,则根据包含-排除原则,没有任何禁止边的循环数为:
sum, for each subset s of S: f(s) * (-1)^|s|
在哪里|s|是 s 中的元素数。换句话说,任何边的循环数的总和减去至少有 1 个禁止边的循环数加上至少有 2 个禁止边的数字,. ..
计算 f(s) 并非易事——至少我没有找到简单的方法。在继续阅读之前,您可能会停下来思考一下。
要计算 f(s),从不涉及任何 s 的节点的排列数开始强>节点。如果有 m 个这样的节点,那么就有 m!排列,如你所知。调用排列数c。
现在检查 s 中的边缘是否有链。如果有任何不可能的组合,例如一个节点涉及3条边或s内的一个子循环,则f(s) 为 0。
否则,对于每个链,将 m 加 1 并将 c 乘以 2m。 (有 m 个位置可以将链放入现有排列中,因子 2 是因为链可以向前或向后。)最后,f(s) 是 c/(2m)。最后一个除法将排列转换为循环。