如果您指出缺少的解释可能会有所帮助,但无论如何我都会尝试...
基于 O(2 k ) 的解决方案使用包含-排除原则。假设有k个禁止边,则这些边有2 k个子集,包括集合本身和空集。例如,如果有 3 个禁止边:{A, B, C},则将有 2 3 =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中的元素数。换句话说,任何边的循环数之和减去至少有 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 )。最后一个除法将排列转换为循环。