今天简单学习了一下2-SAT。现在简单地总结一下。至于定义之类的就不写了,这里就写写做法,以防以后忘记。

构图

每个值a,拆为两个点,一个表示a,一个表示^a(非a)。每个点我们可以看成是一个命题(这是我的理解)。

图中如果有一条边有X连向Y,表示如果X为真,那么可以推出Y为真。

注意,这里的图是有对称性的,这样下面的算法正确性才成立。举个例子,如果a连向b,那么必然有^b连向^a;如果^a连向b,那么必然有^b连向a。

算法

构好图后我们对其使用强连通分量算法。接着我们就可以得到一个有向无环图了,注意,这里的有向无环图依然满足对称性,这个证明比较简单。

然后我们还需要一个拓扑序,这个是强连通分量是自带的一个结果(根据染色的次序就可以判断)。

那么对于每个布尔变量x,让:
x所在的强连通分量的拓扑序在^x所在的强连通分量的拓扑序之后\(\Leftrightarrow\)x为真。

当然,如果存在x和^x在一个强连通分量里面,说明无解。否则按照上面的构造是可以得到一组解的。

正确性

一开始看到这样做,我是持有怀疑态度的,主要是下面两个情况,我想,把这些分析清楚之后,正确性就显而易见了。


情况一:x为真,y为假,但x和y是在同一个强连通分量p里面。

那么^x和^y也在同一个强连通分量q里面。

x为真,p的拓扑序在q的后面。

y为假,p的拓扑序在q的前面。

矛盾。


情况二:x为真,^x为假,y为假,^y为真,存在一条边由x连向y。

根据上面的情况一,这里我们可以把x看作x所在的强连通分量。

x为真,^x为假,x在^x的后面。

存在一条边由x连向y,y在x的后面。

y为假,^y为真,^y在y的后面。

这样我们得到了它们的拓扑序^x,x,y,^y。但是,

存在一条边由^y连向^x,^x在^y的后面。

矛盾。

字典序

利用贪心的思想,每次从最高位开始确定。

如果我们要使x为真,那么就是加一条由^x向x的边,如果行不通,就会使得x和^x在同一个强连通分量里面。所以,我们只需判断加了这条边后有没有一条从x到^x的路径,如果有就不可以让x为真。

所以我们要在一开始时处理出每两两点之间的连通性(\(O(nm)\)),逐一判断真假。使x为真,就加一条由^x向x的边,同理,使x为假就由x连向^x,然后继续维护连通性(\(O(n^2)\))。

事实上,我们并不需要继续维护图的连通性,也就是不加上那些边,不妨把这些边称为没用上的边。试想,如果在后面,需判断没有一条从x到^x的路径,如果需经过一些没用上的边,不妨设其中一条是由u连向v(这里注意u,v一对点),根据对称性可以知道有这样一条回路:x,u,v,^x。所以只需逐一能不能用上这些没用上的边(\(O(n)\))。

这样我们总的复杂度就是\(O(nm+n^2)\)。

这里可能会有些题目使用上述方法过不了,我们可以沿着上面的思路,写一个暴力,虽然最坏情况下依然是\(O(nm)\),但一些简单的剪枝可以使实际运行快得飞起来。

习题

CF 538H

这里有个神奇的解法,如果我们要满足一些数量关系,比如说是限制x的大小的,可以采用这样一个技巧。我们新建一些点,点i表示\(x \leq i\),那么点i的反面就是\(x > i\)。
如果x的大小范围比较大,那么就运用离散化的类似思想,这题的话,我们要选出最终答案可能取的所有值就可以了。

吐槽:我发现我越来越水了,debug了两天。。。。还有,为什么我tarjan的手写栈会慢这么多????!!

话说这题的challenge不会做,他还限制了老师的数量。

CF 587D

这题需要满足的一个东西是,若干的变量里,只能有一个为真或者没有真。假设在x1,x2,...,xn之间只有一个为真。我们可以这样构图:新建点y1,y2,...,yn,加这样一些边xi->yi+1,yi->^xi,当然,还有对应的反边^yi+1->^xi,xi->^yi。

2-SAT 及 一点习题的更多相关文章

  1. 浙大patB习题的一点总结

    嘛嘛,patB的习题已经结束了,这些基本上没有啥特别难的,但还是有几道特别坑爹的题(o(╯□╰)o),还是把这些题的代码打包上传吧.

  2. 模拟CMOS集成电路 课后习题总结(2.1)

    前几天开始自学拉扎维的模设教材,看之前浏览了EETOP论坛里面好多大神们对这本书的看法,当然也有人在抱怨,比如冒出“太科幻”.“一年才看完”之类恐怖的修饰语句,因此在开始看的时候就对此书充满了“敬畏” ...

  3. 《转载》PAT 习题

    博客出处:http://blog.csdn.net/zhoufenqin/article/details/50497791 题目出处:https://www.patest.cn/contests/pa ...

  4. 《数据结构与算法分析:C语言描述_原书第二版》CH2算法分析_课后习题_部分解答

    对于一个初学者来说,作者的Solutions Manual把太多的细节留给了读者,这里尽自己的努力给出部分习题的详解: 不当之处,欢迎指正. 1.  按增长率排列下列函数:N,√2,N1.5,N2,N ...

  5. SICP 习题 (1.7) 解题总结

    SICP 习题 1.7 是对正文1.1.7节中的牛顿法求平方根的改进,改进部分是good-enough?过程. 原来的good-enough?是判断x和guess平方的差值是否小于0.001,这个过程 ...

  6. Python高级编程–正则表达式(习题)

    原文:http://start2join.me/python-regex-answer-20141030/ ############################################## ...

  7. APUE习题8.7

    看书的时候发现这个习题没有答案,于是就想把自己做的结果贴上来,和大家分享分享! 首先把题目贴上来吧: /*********** 8.10节中提及POSIX.1要求在调用exec时关闭打开的目录流.按下 ...

  8. C程序设计 习题之1-20 detab

    码农一定是最需要动手实操的行业之一.有一句话叫,好记性不如烂笔头,牵强附会引申到这里,变成看书百遍,不如码字运行一遍.是不是有那么一点味道?哈哈! 这几天看的<C程序设计>,看完每个章节还 ...

  9. 统计学习导论:基于R应用——第三章习题

    第三章习题 部分证明题未给出答案 1. 表3.4中,零假设是指三种形式的广告对TV的销量没什么影响.而电视广告和收音机广告的P值小说明,原假设是错的,也就是电视广告和收音机广告均对TV的销量有影响:报 ...

随机推荐

  1. RFID电子标签的二次注塑封装

    生活当中,RFID电子标签具有明显的优势,随着RFID电子标签成本的降低.读写距离的提高.标签存储容量增大及处理时间缩短的发展趋势,R F I D电子标签的应用将会越来越广泛. RFID电子标签的应用 ...

  2. C#使用WinAPI 修改电源设置,临时禁止笔记本合上盖子时睡眠

    原文 http://www.cnblogs.com/h46incon/archive/2013/09/03/3299138.html 在 阻止系统自动睡眠的小软件,附C#制作过程 ,弄了一个防止系统睡 ...

  3. Java中String、StringBuilder以及StringBuffer

    原文出处: 海子 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffe ...

  4. Create screenshots of a web page using Python and QtWebKit | Roland's Blog

    Create screenshots of a web page using Python and QtWebKit | Roland's Blog Create screenshots of a w ...

  5. 开始QT+OpenCV学问

    最近一个月.由于超声造影软件工具做.因此,开始接触OpenCV.使用OpenCV的话.除了图像处理,其它功能都非常弱.所以又開始学习MFC. 从原先的.net C#编程环境一下变成MFC还真有点不习惯 ...

  6. sql 时间和字符串 取到毫秒级

    (select replace(replace(replace(CONVERT(varchar, getdate(), 120 ),'-',''),' ',''),':','')+(Select ri ...

  7. 使用数据库绑定ListBox控件

    1. The HTML Markup <div> <asp:ListBox ID="ListBox1" runat="server">& ...

  8. CSS的z-index(分层)

    z-index是针对网页显示中的一个特殊属性.因为显示器是显示的图案是一个二维平面,拥有x轴和y轴来表示位置属性.为了表示三维立体的概念如显示元素的上下层的叠加顺序引入了z-index属性来表示z轴的 ...

  9. virtual 关键字

    virtual 关键字用于修饰方法.属性.索引器或事件声明,并且允许在派生类中重写这些对象.例如,此方法可被任何继承它的类重写. public virtual double Area() { retu ...

  10. discuz bbs注册,登录流程整理!想打通bbs又不想读一遍代码可以参考一下

    bbs 用户注册流程 第一步: /source/class/class_member.php: on_register注册入口 L602 左右 if(!$activation) {//不为空,说明用户 ...