2-sat
2-sat
2-sat是用来解决如下问题形式的算法:
有 \(n\)个布尔变量 \(x_1\sim x_n\),另有 \(m\)个需要满足的条件,每个条件的形式都是" \(x_i\) 为
true
/false
或 \(x_j\)为true
/false
"。
算法的原理是将\(x_i\)为真和\(x_i\)为假拆成两个状态(点),通过建立"若 \(x\) 真/假则 \(y\) 必真/假"的关系(边),将约束条件转化为了一个有向图。
-
具体连边方式举例:
\(a\lor b:\) \(\neg a\rightarrow b\;,\;\neg b\rightarrow a\) 理解为:若\(a\)假则\(b\)必真,若 \(b\) 假则 \(a\)必真
在这个有向图中,只要确定了某一个点,那么他连向的所有点都确定了。在这里,确定的含义是依据该点状态(是真是假)确定了该点的编号是真还是假。
所以我们可以先缩点,缩点之后的DAG中,当”x为真“所在的强连通分量的拓扑序在”x为假“所在的强连通分量的拓扑序之后取 x 为真。(体现在强连通分量的编号上是编号小的在编号大的下面)
原因:如果是拓扑序小的状态确定了,那么就有可能会导致拓扑序大的状态同时确定,就矛盾了。反之,如果确定拓扑序大的点,那么小的点一定不会被确定,也就不会产生矛盾。
一个奇怪的性质:连边的时候\(x\)和\(\neg x\)所连的边具有对称性(相反性),即\(x\rightarrow y\),那么\(\neg y\rightarrow \neg x\),而且如果\(x\)最后强连通分量内的点有\(y\),那么\(\neg x\)所在的强连通分量一定会有\(\neg y\),而且边的方向相反。