算法笔记 - 2-SAT
概述
(挂个定义)
SAT 是适定性 (Satisfiability) 问题的简称。一般形式为 k - 适定性问题,简称 k-SAT。而当 k>2 时该问题为 NP 完全的。所以我们只研究 k=2 的情况。
2-SAT,简单的说就是给出 n 个集合,每个集合有两个元素,已知若干个 <a,b>,表示 a 与 b 矛盾(其中 a 与 b 属于不同的集合)。然后从每个集合选择一个元素,判断能否一共选 n 个两两不矛盾的元素。显然可能有多种选择方案,一般题中只需要求出一种即可。
求解
模板题
有 \(n\) 个布尔变量 \(x_1\sim x_n\),另有 \(m\) 个需要满足的条件,每个条件的形式都是 「\(x_i\) 为
true
/false
或 \(x_j\) 为true
/false
」。比如 「\(x_1\) 为真或 \(x_3\) 为假」、「\(x_7\) 为假或 \(x_2\) 为假」。
我们以下称每个变量的某种取值(或者说一种方案)为文字,连有向边的逻辑关系是 \(\boldsymbol{蕴含}\) ,或者说 \(\boldsymbol{意味着}\) 。(也可以理解为命题的条件和结论)
将 \(x_i=1\) 的文字记作 \(x_i\) , 将 \(x_i=0\) 的文字记作 \(\neg x_i\) 。
\((u, v)\) 表示一条从 \(u\) 连向 \(v\) 的有向边。
举个例子, 限制 \(x_1 = true\) \(\vee\) \(x_2 = false\) 就可以通过 \((\neg x_1,\neg x_2)\) , \(x_2, x_1\) 来刻画。
表示:如果 \(x_1 = false\) ,那么意味着 \(x_2 = false\) 同样成立;如果 \(x_2 = true\) ,那么意味着 \(x_1 = true\) 同样成立。
现在来说明解法,按照如上含义建出有向图后缩强联通分量 (可以通过 Tarjan 或 Kosaraju )。
如果 \(x_i\) 和 \(\neg x_i\) 属于同一个 \(SCC\) ,那么不合法,否则,取拓扑序更大的文字作为方案。
在 \(Tarjan\) 中,编号是倒序的拓扑序,而在 \(Kosaraju\) 算法中,编号直接就是拓扑序。
证明
首先,必要性是显然的。
下面来考虑这种方式为什么一定不会构造出不合法的方案。
首先一个文字本身不会出现矛盾,下面来反证一个文字不会导致另一个文字矛盾。
不妨设我们最终选择了 \(a\), \(b\) 两个文字,记 \(d\) 表示拓扑序,则 \(d_a > d_{\neg a}\) , \(d_b > d_{\neg b}\) ,如果不合法,则 \(a\) 可以到达 \(\neg b\) , \(d_{\neg b} > d_a\) 同时,观察以上的连边,如果按照命题的方式理解,那么一个命题成立,它的逆否命题也一定成立,所以, \(b\) 一定也可以到达 \(\neg a\) , \(d_{\neg a} > d_b\) 。
整理上述式子得到 \(d_a > d_{\neg a} > d_b > d_{\neg b} > d_a\) ,即 \(d_a > d_a\) ,矛盾,所以上述方法构造出的方案合法。
并且发现,只有连边时保证一个命题成立,那么它的逆否命题也一定成立,算法才是正确的。
例题
时间仓促,如有错误欢迎指出,欢迎在评论区讨论,如对您有帮助还请点个推荐、关注支持一下