zoukankan      html  css  js  c++  java
  • 2-SAT浅谈

    2-SAT浅谈

    一、2-SAT问题

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

    二、解法

      对于这样的问题,我们运用对称的思想进行建图。我们一下面给出的问题为例:现在给出$n$个物品和$m$个限制条件,每一个物品有两种状态:购买或不购买;每一个限制条件可以用四元组表示:$(x,a,y,b)$,其中$a,bin {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 ightarrow b$的含义:如果要选择$a$这个状态,则必须选择$b$这个状态。

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

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

  • 相关阅读:
    Linux 常用命令
    去除重叠区间
    Python 小工具之大文件去重
    有趣的pyfiglet
    杨辉三角
    Paginator分页
    Linux用户和用户组
    Grub介绍
    Linux系统运行级别
    Linux系统启动流程
  • 原文地址:https://www.cnblogs.com/yangsongyi/p/10246213.html
Copyright © 2011-2022 走看看