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

Great_Influence关于P4782 【模板】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基础详解的更多相关文章

  1. Dom探索之基础详解

    认识DOM DOM级别 注::DOM 0级标准实际并不存在,只是历史坐标系的一个参照点而已,具体的说,它指IE4.0和Netscape Navigator4.0最初支持的DHTML. 节点类型 注:1 ...

  2. Android中Canvas绘图基础详解(附源码下载) (转)

    Android中Canvas绘图基础详解(附源码下载) 原文链接  http://blog.csdn.net/iispring/article/details/49770651   AndroidCa ...

  3. javaScript基础详解(1)

    javaScript基础详解 首先讲javaScript的摆放位置:<script> 与 </script> 可以放在head和body之间,也可以body中或者head中 J ...

  4. Python学习一:序列基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...

  5. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

  6. 深入浅出DOM基础——《DOM探索之基础详解篇》学习笔记

    来源于:https://github.com/jawil/blog/issues/9 之前通过深入学习DOM的相关知识,看了慕课网DOM探索之基础详解篇这个视频(在最近看第三遍的时候,准备记录一点东西 ...

  7. 三剑客基础详解(grep、sed、awk)

    目录 三剑客基础详解 三剑客之grep详解 1.通配符 2.基础正则 3.grep 讲解 4.拓展正则 5.POSIX字符类 三剑客之sed讲解 1.sed的执行流程 2.语法格式 三剑客之Awk 1 ...

  8. java继承基础详解

    java继承基础详解 继承是一种由已存在的类型创建一个或多个子类的机制,即在现有类的基础上构建子类. 在java中使用关键字extends表示继承关系. 基本语法结构: 访问控制符 class 子类名 ...

  9. java封装基础详解

    java封装基础详解 java的封装性即是信息隐藏,把对象的属性和行为结合成一个相同的独立单体,并尽可能地隐藏对象的内部细节. 封装的特性是对属性来讲的. 封装的目标就是要实现软件部件的"高 ...

  10. Java :内部类基础详解

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 第一次见面 内部类我们从外面看是非常容易理解的,无非就是在一个类的内部在定义一个类. public class OuterClass { pr ...

随机推荐

  1. Java文件读写分析

    本文内容:IO流操作文件的细节分析:分析各种操作文件的方式. 读写一个文件 从一个示例开始分析,如何操作文件: /** * 向一个文件中写入数据 * @throws IOException */ pr ...

  2. C++多线程基础学习笔记(四)

    一.创建多个子线程 前面三章讲的例子都是只有一个子线程和主线程,然而实际中有多个子线程.那么下面介绍如何创建多个子线程. #include <iostream> #include < ...

  3. Python基础字符串前加u,r,b,f含义

    1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用: 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时 ...

  4. Redis: 缓存过期、缓存雪崩、缓存穿透、缓存击穿(热点)、缓存并发(热点)、多级缓存、布隆过滤器

    Redis: 缓存过期.缓存雪崩.缓存穿透.缓存击穿(热点).缓存并发(热点).多级缓存.布隆过滤器 2019年08月18日 16:34:24 hanchao5272 阅读数 1026更多 分类专栏: ...

  5. 搭建springCloud网关zuul

    一.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...

  6. SpringBoot上传文件,经过spingCloud-Zuul,中文文件名乱码解决办法

    最近用springCloud整合springboot做分布式服务发现经过zuul之后上传的中文文件名乱码全都变成?????,从而引发异常,单独用springboot却是好的,在网上找到相关资料总结如下 ...

  7. MySQL主从延时这么长,要怎么优化?

    MySQL主从复制,读写分离是互联网常见的数据库架构,该架构最令人诟病的地方就是,在数据量较大并发量较大的场景下,主从延时会比较严重. 为什么主从延时这么大? 答:MySQL使用单线程重放RelayL ...

  8. Docker简易使用手册

    1. Docker介绍 Docker中文社区文档 Docker 是一个开源的软件部署解决方案. Docker 包括三个基本概念: 镜像(Image) Docker的镜像概念类似于虚拟机里的镜像,是一个 ...

  9. centos查看实时网络带宽占用情况方法【转】

    Linux中查看网卡流量工具有iptraf.iftop以及nethogs等,iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息等. centos安装iftop的命令如下: ...

  10. debezium关于cdc的使用(下)

    博文原址:debezium关于cdc的使用(下) 简介 debezium在debezium关于cdc的使用(上)中有做介绍.具体可以跳到上文查看.本篇主要讲述使用kafka connector方式来同 ...