2-SAT浅谈

一、2-SAT问题

  首先,什么是$2-SAT$问题。现在给出这样一类问题:给出$n$个点和关于这$n$个点的$m$条限制条件,并且这$n$个点中,每一个点只有两种状态。对于上述问题,我们称之为$2-SAT$问题。如果这些点中有一个点的状态总数大于$2$,这个问题就不能称之为$2-SAT$问题。

二、解法

  对于这样的问题,我们运用对称的思想进行建图。我们一下面给出的问题为例:现在给出$n$个物品和$m$个限制条件,每一个物品有两种状态:购买或不购买;每一个限制条件可以用四元组表示:$(x,a,y,b)$,其中$a,b\in \{0,1\}$,$0$表示不选,反之$1$表示选。这个四元组,表示我们在$x$物品为$a$状态和$y$物品为$b$状态这两个事件中至少要选取一个,是之成立。

  对于上述问题,我们就可以向每一个节点分配两个节点,即对于第$i$个物品分配编号为$(i<<1)$和$(i<<1|1)$两个节点,分别表示选择这个物品或者不选择这个物品。如果要满足上述的四元组,我们知道一个性质:如果不选$x$为$a$状态这个事件,则我们一定选择$y$为$b$状态这个事件;如果不选$y$为$b$状态这个事件,则我们一定选择$x$为$a$状态这个事件。根据这个性质我们可以进行连边,我们从$(x<<1|(a==1))$连接一条有向边至$(y<<1|(b==1))\oplus1$,从$(y<<1|(b==1))$连接一条有向边至$(x<<1|(a==1))\oplus1$,这两条有向边的含义就是上述性质。对于一条有向边$a\rightarrow b$的含义:如果要选择$a$这个状态,则必须选择$b$这个状态。

  $O(n^2)$做法:根据上述含义,我们知道如果要选择$a$状态,则在我们所建出的图中能从$a$到达的状态点我们都必须要选择,对于这个性质,我们可以对于每一个状态点我们都遍历整张图,这样只需要判断我们判断这个点能到达的点中是否有与其向排斥的点,即是否存在一个点的编号异或$1$之后的值与其相同$(点的编号\oplus 1== 出发点编号)$,若有则有点和他相违背,这样我们这个点所表达的状态就不能成立,若同一个物品的两个状态都不能成立,则这组限制条件没有办法成立。

  $O(n)$做法:我们发现一个四元组:$(x,a,y,b)$所形成的边一定实对称的,即若有一条有向边$x\rightarrow y$,则一定有一条有向边$y\oplus1\rightarrow x\oplus1$。我们根据这个性质知道,若一个物品的两个状态都不可能成立,则这两个点一定相连,且在一个环上。简单的小证明:如果$x$不成立,则$x$一定能通过边到达$x\oplus1$,因为上述性质,所以$x\oplus1$也能通过边到达$x$,又因为这是一个有向图,所以他们一定在一个环上。运用这个性质,我们可以运用$tarjan$,进行缩点,若有一对点$x、x\oplus1$,在缩点之后属于一个强连通分量中,则这组限制条件不成立。对于方案,我们也能在线性时间复杂度内求出一组方案。我们先对我们建出的图进行缩点操作,在缩点之后我们将剩下的所有边反向重连,对于这个图跑拓扑序。当然这个只是按照拓扑序的思路,对于当前强连通分量,若我们选择他,则他中所有的点的对应点所在强连通分量都不能选,依照这个我们进行拓扑排序和选择答案。

2-SAT浅谈的更多相关文章

  1. 【WebApi系列】浅谈HTTP

    [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi如何传递参数 [04]详解WebApi测试和PostMan [05]浅谈WebApi Core ...

  2. 【WebApi系列】浅谈HTTP在WebApi开发中的运用

    WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...

  3. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  4. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  5. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  6. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  7. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  8. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  9. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  10. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

随机推荐

  1. 《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目7

    2014-04-24 22:06 题目:搜索引擎问题,如果有一列100台服务器的集群,用来响应查询请求,你要如何设计query分发和cache策略? 解法:query分发可以用计算数字签名并对机器数取 ...

  2. USACO Section2.3 Zero Sum 解题报告 【icedream61】

    zerosum解题报告----------------------------------------------------------------------------------------- ...

  3. 每天一个Linux命令(1):cd命令

    cd命令用来切换工作目录至dirName,其中dirName表示绝对路径或相对路径.若目录名称省略,则切换至使用者的home directory(也就是钢login时所在的目录).另外,~ 也表示ho ...

  4. hadoop +streaming 排序总结

    参考http://blog.csdn.net/baidu_zhongce/article/details/49210787 hadoop用于对key的排序和分桶的设置选项比较多,在公司中主要以KeyF ...

  5. 删除maven仓库中的lastUpdate文件

    使用idea时导入hibernate 5.1.0的jar包,然后发现本地仓库中找不到该版本的jar 然后手贱 alt+enter 发现提示 update maven indices 然后以为更新就会好 ...

  6. android自定义控件属性

    有两种方法为自定义的控件设置属性 . 来自为知笔记(Wiz)

  7. js 回车触发点击事件

    $(document).keyup(function(event){ if(event.keyCode ==13){ $("#submit").trigger("clic ...

  8. Spring Boot RabbitMQ 延迟消息实现完整版

    概述 曾经去网易面试的时候,面试官问了我一个问题,说 下完订单后,如果用户未支付,需要取消订单,可以怎么做 我当时的回答是,用定时任务扫描DB表即可.面试官不是很满意,提出: 用定时任务无法做到准实时 ...

  9. 3.1 Java以及Lucene的安装与配置

    Lucene是Java开发的一套用于全文检索和搜索的开源程序库,它面向对象多层封装,提供了一个低耦合.与平台无关的.可进行二次开发的全文检索引擎架构,是这几年最受欢迎的信息检索程序库[1].对Luce ...

  10. js加解密的算法

    //字符串和数字互转 var str="a" var r = str.charCodeAt(0); //97 10进制 console.log(r); var t=String.f ...