2-sat基础详解
(大量引用《2-SAT解法浅析 -by 华中师大一附中 赵爽》《由对称性解2-SAT问题》

在实际的题目中,限制往往还有除了或以外的别的形式,这些限制也将在这篇文章中讨论。
先讨论以下两类限制的情况:
1、若x=a,则y=b
2、x=a或y=b
由于x、y都是bool变量,值要么1,要么0,所以可以通过建有向图的方式来表示这个题目。对每个bool变量x,都建立两个点,分别表示x=1和x=0。为了方便,以后的x表示图中的一个点(除非x前加“变量”两字,表示变量),~x表示点x的对应点(即另一个表示同一变量的点)。图中有了点,就要考虑边了。
设X_a (字母大写以区分上文小写字母表示内容)为变量x等于一个数a对应的点。同时下文的‘^’表示异或符号。显然对上面的两类限制都可以通过连边实现:
对于第一种限制,要增这样两条边:(X_a,Y_b)即变量x=a可推出变量y=b;(Y_(b^1),X_(a^1))即变量y不等于b可推出变量x不等于a。
对于第二种限制,就要增这样两条边:(X_(a^1),Y_b)即变量x不等于a可推出变量y等于b;(Y_(b^1),X_a)即变量y不等于b可推出变量x不等于a。
发现这些边都是对称的,即若连了一条边(x,y),则必会有边(~y,~x)(注意这里的字母是小写的)在同一时间连上。同时也发现这些边的意义也很好理解,不就是“推出”嘛。并且每种限制所连的两条边都很好地将这个限制表示了出来。那么有了一个最基本的解决问题的暴力算法了:从每个变量x开始,若它有标记,则直接看下一个变量,否则枚举它选1或选0,设选了b,并从相应的点dfs。在dfs过程中标记遍历过的变量都选什么(对正向边则标记为该边的终点;反向边则标记为该边的对应点。是的,这个dfs也要走反向边,即一切有关系的都要走)。若发现dfs过程中遍历了一组对应点,即从当前变量x选b可推出某个变量既选1又选0,这显然是矛盾的,故当前变量不能选b,要选另一个。若当前变量选1或0都不行,则无解了(这里用不用让之前的变量重新选一下,再重新枚举当前变量的取值呢?答案是不用。因为若当前变量要取枚举取1取0,则当前变量肯定与之前变量关系。因为有关系的都被打上标记了。所以之前变量的取值情况是与当前变量独立的);否则就看下一个变量: 直到看完所有变量的值后发现仍没有矛盾,则每个变量枚举的值就是答案;或发现无解情况,就记录无解信息后停止就好。
显然这个算法是很慢的,时间复杂度可达O(n*m)。除非要求一个字典序最小的取值方案,否则一般都不用这个算法。下面介绍一个更快的算法:
我们考虑图的一个强连通分量。很明显,如果我们选中强连通分量中的任何一点,那么该强连通分量中的所有其它的顶点也必须被选择。所以我们可以先求图的所有强联通分量。当我们发现若一组对应点x和~x都在同一个强连通分量时,即若变量x选1,可推出它应该选0;它选0,可推出它应该选1,这样的话变量x不管怎么选都是矛盾的,则该2-sat无解。若没有这样的情况,那么我就叫他“前置合法”了,即已经满足了有解的前提之一。前置合法后,设原图为G,缩点后的图为G',然后,我们把G'中的所有弧反向,得到图G′′。由于已经进行了缩点的操作,因此G′′中一定不存在圈,也就是说,G''具有拓扑结构。我们把G中所有顶点置为“未着色”。按照拓扑顺序重复下面的操作:
1、选择第一个未着色的顶点u。把u染成红色。
2、把所有与u矛盾的顶点(如果存在x,~x∈
,
前置合法时,k=1建的边不会影响强连通分量的对称性。(因为这条边的起点与终点不会在同一个强联通分量里)。
证明正确性前先了解几个定理:
1、
2、
3、
下面证明一下该算法的正确性:
一、
二、
1、
个人认为《2-SAT解法浅析》中有关二、1的证明是不正确的,这里可以举出一个反例:
所以下文给出作者个人的关于二、1的证明:
2、
故该算法是正确的。时间复杂度为O(n)(tarjan为O(n),拓扑排序为O(n),染色为O(n)(染色要注意不染重复的点,否则就可能变成O(n的平方))。故总复杂度也为O(n)(实际上,更准确的说,这里的n为n*2))
其实还有一个常数的优化:
故前置合法时必有解
故前置合法时,每个变量选他对应点中拓补序大的点,一定会得到一组解。这样的话就不用求完拓补序后再染色了。
再仔细考虑一下,发现tarjan的缩点的顺序正是一个反的拓补序,所以可以记录他tarjan的顺序,这样连拓扑序也不用求了。
代码
2-sat基础详解的更多相关文章
- Dom探索之基础详解
认识DOM DOM级别 注::DOM 0级标准实际并不存在,只是历史坐标系的一个参照点而已,具体的说,它指IE4.0和Netscape Navigator4.0最初支持的DHTML. 节点类型 注:1 ...
- Android中Canvas绘图基础详解(附源码下载) (转)
Android中Canvas绘图基础详解(附源码下载) 原文链接 http://blog.csdn.net/iispring/article/details/49770651 AndroidCa ...
- javaScript基础详解(1)
javaScript基础详解 首先讲javaScript的摆放位置:<script> 与 </script> 可以放在head和body之间,也可以body中或者head中 J ...
- Python学习一:序列基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
- 深入浅出DOM基础——《DOM探索之基础详解篇》学习笔记
来源于:https://github.com/jawil/blog/issues/9 之前通过深入学习DOM的相关知识,看了慕课网DOM探索之基础详解篇这个视频(在最近看第三遍的时候,准备记录一点东西 ...
- 三剑客基础详解(grep、sed、awk)
目录 三剑客基础详解 三剑客之grep详解 1.通配符 2.基础正则 3.grep 讲解 4.拓展正则 5.POSIX字符类 三剑客之sed讲解 1.sed的执行流程 2.语法格式 三剑客之Awk 1 ...
- java继承基础详解
java继承基础详解 继承是一种由已存在的类型创建一个或多个子类的机制,即在现有类的基础上构建子类. 在java中使用关键字extends表示继承关系. 基本语法结构: 访问控制符 class 子类名 ...
- java封装基础详解
java封装基础详解 java的封装性即是信息隐藏,把对象的属性和行为结合成一个相同的独立单体,并尽可能地隐藏对象的内部细节. 封装的特性是对属性来讲的. 封装的目标就是要实现软件部件的"高 ...
- Java :内部类基础详解
可以将一个类的定义放在另一个类的定义内部,这就是内部类. 第一次见面 内部类我们从外面看是非常容易理解的,无非就是在一个类的内部在定义一个类. public class OuterClass { pr ...
随机推荐
- Nginx linux下的安装
1.先把从官网 nginx.io下载 的安装包通过ftp传到服务器上,然后进行解压. 我的安装环境以及nginx版本 :Ubuntu16 ,nginx-1.11.3.tar.gz(经过这个尝试这个版本 ...
- AppCan全局搜索
Ctrl + H,在项目中全局搜索英文和中文
- 滚动页面产生动画WOW.js的用法
简介 在一些网页上,当你滚动页面的时候会看到各式各样的元素动画效果,非常动感.WOW.js 就是一款帮助你实现这种 CSS 动画效果的插件.WOW.js 依赖 animate.css,所以它支持 an ...
- vscode中eslint插件的配置-prettier
用vue-cli构建vue项目,会有个eslint代码检测的安装 可vscode自带代码格式化是prettier格式(右键有格式化文件或alt+shift+f) 这时候要在vscode上装一个esli ...
- Codeforces 1201E2. Knightmare (hard)
传送门 看到棋盘先黑白染色冷静一下 然后分析发现,如果初始时两只马在同色的格子,那么一定是后手吃先手 反之一定是先手吃后手 所以分类讨论一下,如果初始在同色的格子,并且后手到达终点的步数更少,那么后手 ...
- java保留小数点的几个方法
方法一: String类自带的方法 String.format("%.2f", 1.2548); "%.2f"其中的数字决定保留几位方法二: 格式化的方法 pr ...
- JsonObject、JsonArray操作json的个人总结
介绍 JsonObject.JsonArray之前,先介绍下JsonConfig JsonConfig: setClassMap(Map classMap)设置json属性类型,上json里的其中值为 ...
- Git复习(二)之远程仓库、注册GitHub账号、SSH警告、使用GitHub
远程仓库 Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上.怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都 ...
- MongoDB v4.0 命令
MongoDB v4.0 命令 官方文档 > 点这里 < 操作系统库 #操作管理员库 use admin #鉴权 db.auth("root","admin& ...
- JSTL标签+El表达式把list集合数据展示到 JSP页面
JSP页面 <%@ page import="cn.itcast.domain.User" %><%@ page import="java.util.L ...