跳过正文
  1. Posts/

【2-SAT问题】(转自kuangbin的博客)

·5 分钟

【2-SAT问题】 现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x] AND A[y]=0、A[x] OR A[y] OR A[z]=1等,要确定A[0..N-1]的值,使得其满足所有限制关系。这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题。

由于在2-SAT问题中,最多只对两个元素进行限制,所以可能的限制关系共有11种: A[x] NOT A[x] A[x] AND A[y] A[x] AND NOT A[y] A[x] OR A[y] A[x] OR NOT A[y] NOT (A[x] AND A[y]) NOT (A[x] OR A[y]) A[x] XOR A[y] NOT (A[x] XOR A[y]) A[x] XOR NOT A[y] 进一步,A[x] AND A[y]相当于(A[x]) AND (A[y])(也就是可以拆分成A[x]与A[y]两个限制关系),NOT(A[x] OR A[y])相当于NOT A[x] AND NOT A[y](也就是可以拆分成NOT A[x]与NOT A[y]两个限制关系)。因此,可能的限制关系最多只有9种。

在实际问题中,2-SAT问题在大多数时候表现成以下形式:有N对物品,每对物品中必须选取一个,也只能选取一个,并且它们之间存在某些限制关系(如某两个物品不能都选,某两个物品不能都不选,某两个物品必须且只能选一个,某个物品必选)等,这时,可以将每对物品当成一个布尔值(选取第一个物品相当于0,选取第二个相当于1),如果所有的限制关系最多只对两个物品进行限制,则它们都可以转化成9种基本限制关系,从而转化为2-SAT模型。

【建模】 其实2-SAT问题的建模是和实际问题非常相似的。 建立一个2N阶的有向图,其中的点分为N对,每对点表示布尔序列A的一个元素的0、1取值(以下将代表A[i]的0取值的点称为i,代表A[i]的1取值的点称为i’)。显然每对点必须且只能选取一个。然后,图中的边具有特定含义。若图中存在边,则表示若选了i必须选j。可以发现,上面的9种限制关系中,后7种二元限制关系都可以用连边实现,比如NOT(A[x] AND A[y])需要连两条边和,A[x] OR A[y]需要连两条边和。而前两种一元关系,对于A[x](即x必选),可以通过连边来实现,而NOT A[x](即x不能选),可以通过连边来实现。

【O(NM)算法:求字典序最小的解】 根据2-SAT建成的图中边的定义可以发现,若图中i到j有路径,则若i选,则j也要选;或者说,若j不选,则i也不能选; 因此得到一个很直观的算法: (1)给每个点设置一个状态V,V=0表示未确定,V=1表示确定选取,V=2表示确定不选取。称一个点是已确定的当且仅当其V值非0。设立两个队列Q1和Q2,分别存放本次尝试选取的点的编号和尝试不选的点的编号。 (2)若图中所有的点均已确定,则找到一组解,结束,否则,将Q1、Q2清空,并任选一个未确定的点i,将i加入队列Q1,将i’加入队列Q2; (3)找到i的所有后继。对于后继j,若j未确定,则将j加入队列Q1;若j’(这里的j’是指与j在同一对的另一个点)未确定,则将j’加入队列Q2; (4)遍历Q2中的每个点,找到该点的所有前趋(这里需要先建一个补图),若该前趋未确定,则将其加入队列Q2; (5)在(3)(4)步操作中,出现以下情况之一,则本次尝试失败,否则本次尝试成功: <1>某个已被加入队列Q1的点被加入队列Q2; <2>某个已被加入队列Q2的点被加入队列Q1; <3>某个j的状态为2; <4>某个i’或j’的状态为1或某个i’或j’的前趋的状态为1; (6)若本次尝试成功,则将Q1中的所有点的状态改为1,将Q2中所有点的状态改为2,转(2),否则尝试点i’,若仍失败则问题无解。 该算法的时间复杂度为O(NM)(最坏情况下要尝试所有的点,每次尝试要遍历所有的边),但是在多数情况下,远远达不到这个上界。 具体实现时,可以用一个数组vst来表示队列Q1和Q2。设立两个标志变量i1和i2(要求对于不同的i,i1和i2均不同,这样可以避免每次尝试都要初始化一次,节省时间),若vst[i]=i1则表示i已被加入Q1,若vst[i]=i2则表示i已被加入Q2。不过Q1和Q2仍然是要设立的,因为遍历(BFS)的时候需要队列,为了防止重复遍历,加入Q1(或Q2)中的点的vst值必然不等于i1(或i2)。中间一旦发生矛盾,立即中止尝试,宣告失败。

该算法虽然在多数情况下时间复杂度到不了O(NM),但是综合性能仍然不如下面的O(M)算法。不过,该算法有一个很重要的用处:求字典序最小的解! 如果原图中的同一对点编号都是连续的(01、23、45……)则可以依次尝试第0对、第1对……点,每对点中先尝试编号小的,若失败再尝试编号大的。这样一定能求出字典序最小的解(如果有解的话),因为一个点一旦被确定,则不可更改。 如果原图中的同一对点编号不连续(比如03、25、14……)则按照该对点中编号小的点的编号递增顺序将每对点排序,然后依次扫描排序后的每对点,先尝试其编号小的点,若成功则将这个点选上,否则尝试编号大的点,若成功则选上,否则(都失败)无解。

1、HDU 3622 Bomb Game

2-sat构图进行可行性判断问题。二分+2-sat求解。

解题报告here

HDU 3622

HDU 3622

2、HDU 1814 Peaceful Commission

2-sat题目。要求输出字典序最小解。

解题报告见here

输出字典序最小的解的程序:

HDU 1814

另外写了一个输出任意一组解的程序:

HDU 1814

3、POJ 3207 Ikki’s Story IV - Panda’s Trick

** 可行性判断**

解题报告见here

POJ 3207

4、POJ 2296 Map Labeler

二分+2-SAT可行性判断

** 和HDU 3644很相似的方法。**

解题报告here

POJ 2296

5、POJ 3648 Wedding

此题陷进比较多。要输出一组解的2-SAT。

POJ 3648

POJ 3648

6、POJ 3678 Katu Puzzle

给出一些两两之间的AND,OR,XOR表达式的值,问有没有解。

经典的2-SAT问题。简单。

POJ 3678

7、HDU 4115 Eliminate the Conflict

2-SAT判断是否有解问题。主要是要细心,注意细节。

HDU 4115

相关文章

斯特林数

·1 分钟
http://baike.baidu.com/link?url=nsN1-rcs3Gs0jNurWLSDk6AJ9jmhl_3pfkQmYK7vZoe7BsoTij48Si3It9XeNM4uA7gST-1ITQsAx0bv5si9_q

cf 570 C. Replacement (暴力)

·2 分钟
C. Replacement time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Daniel has a string s, consisting of lowercase English letters and period signs (characters ‘.’). Let’s define the operation of replacement as the following sequence of steps: find a substring “..” (two consecutive periods) in string s, of all occurrences of the substring let’s choose the first one, and replace this substring with string “.”. In other words, during the replacement operation, the first two consecutive periods are replaced by one. If string s contains no two consecutive periods, then nothing happens.