简介

2-SAT (2-satisfiability) 问题形如:

  1. 给定一些变量 \(x_i \in \{true, false\}\);
  2. 给定一些一元/二元约束条件, 如 \(x_i \land \lnot x_j\), 利用 \(\land\) 连接;
  3. 为每一个变量赋一个值, 满足所有约束条件.

将第2条中的一/二元约束条件改为多元, 即为 N-SAT 问题.

可以证明 N-SAT 问题没有多项式解法, 但 2-SAT 问题有 \(O(n + m)\) 的解法.

算法

对每个变量建立两个点: \(x_i\), \(x_i'\), 表示取真或假.

根据约束条件建立若干条边 \((p, q)\), 表示若选 \(p\) 则必须选 \(q\). (见下)

将得到的图缩点. 若 \(x_i\) 和 \(x_i'\) 在同一个强连通分量内, 则无解.

否则, 若 \(x_i\) 的所在强连通分量的拓扑序大于 \(x_i'\), 则选 \(x_i\); 否则选 \(x_i'\).

我们知道tarjan算法求出的强连通分量标号为强连通分量拓扑序的逆序. 因此判断 \(scc_{x_i} < scc_{x_i'}\) 即可.

建边

  1. 一元逻辑

    1. \(p\): \((p', p)\);
    2. \(\lnot p\): \((p, p')\).
  2. 二元逻辑 (\(p\) 和 \(\lnot p\) 是一样的, 下面仅描述 \(p\) 的情况)
    1. \(p \rightarrow q\): \((p, q)\), \((q', p')\);
    2. \(p \land q\): 等价于 \(p\), \(q\);
    3. \(p \lor q\): \((p', q)\), \((q', p)\) (等价于 \(\lnot p \rightarrow q\));
    4. \(p \oplus q\): \((p, q')\), \((p', q)\), \((q, p')\), \((q', p)\). (xor)

容易发现所有二元逻辑都会建立若干对边, 这称作2-SAT问题的对称性, 是算法正确的关键.

较慢的算法 && 字典序最小解

我们还可以枚举每个点, 然后假设其为 true (或者 false), 从该点dfs判断是否可行.

这样可以求出一些特殊条件的解, 如最小字典序.

时间复杂度 \(O(nm)\), 但是多数情况跑不满.

代码

//任意解
int chos[nsz];
int dfn[nsz*2],pd=0,low[nsz*2],inscc[nsz*2],ps=0;
int stk[nsz*2],top=0,vi[nsz*2];
void tarj(int p){
dfn[p]=low[p]=++pd;
stk[++top]=p,vi[p]=1;
for(auto v:edge[p]){
if(dfn[v]==0){
tarj(v);
low[p]=min(low[p],low[v]);
}
else if(vi[v])low[p]=min(low[p],dfn[v]);
}
if(low[p]==dfn[p]){//scc
++ps;
int v;
do{
v=stk[top];
inscc[v]=ps,vi[v]=0,--top;
}while(v!=p);
}
} bool sat2(){//toefl ielts sat
rep(i,2,n*2+1)if(dfn[i]==0)tarj(i);
rep(i,1,n){
if(inscc[i<<1]==inscc[i<<1|1])return 0;//no solution
chos[i]=inscc[i<<1|1]<inscc[i<<1];
}
return 1;
}

[模板] 2-SAT 问题的更多相关文章

  1. 2 - sat 模板(自用)

    2-sat一个变量两种状态符合条件的状态建边找强连通,两两成立1 - n 为第一状态(n + 1) - (n + n) 为第二状态 例题模板 链接一  POJ 3207 Ikki's Story IV ...

  2. TwoSAT算法模板

    该模板来自大白书 [解释] 给多个语句,每个语句为“ Xi为真(假) 或者 Xj为真(假)” 每个变量和拆成两个点 2*i为假, 2*i+1为真 “Xi为真 或 Xj为真”  等价于 “Xi为假 –& ...

  3. C++ 模板基础

    我们学习使用C++,肯定都要了解模板这个概念.就我自己的理解,模板其实就是为复用而生,模板就是实现代码复用机制的一种工具,它可以实现类型参数化,即把类型定义为参数:进而实现了真正的代码可重用性.模版可 ...

  4. (模板)poj2947(高斯消元法解同余方程组)

    题目链接:https://vjudge.net/problem/POJ-2947 题意:转换题意后就是已知m个同余方程,求n个变量. 思路: 值得学习的是这个模板里消元用到lcm的那一块.注意题目输出 ...

  5. 虚拟化技术之kvm镜像模板制作工具virt-sysprep

    virt-sysprep这个工具来自libguest-tools这个工具包,它能够把kvm虚拟机对应的磁盘文件做成一个模板,后续我们启动虚拟机就可以基于这个镜像模板启动:什么是镜像模板呢?所谓模板就是 ...

  6. Jade模板引擎让你飞

    写在前面:现在jade改名成pug了 一.安装 npm install jade 二.基本使用 1.简单使用 p hello jade! 渲染后: <p>hello jade!</p ...

  7. ABP入门系列(2)——通过模板创建MAP版本项目

    一.从官网创建模板项目 进入官网下载模板项目 依次按下图选择: 输入验证码开始下载 下载提示: 二.启动项目 使用VS2015打开项目,还原Nuget包: 设置以Web结尾的项目,设置为启动项目: 打 ...

  8. CMS模板应用调研问卷

    截止目前,已经有数十家网站与我们合作,进行了MIP化改造,在搜索结果页也能看到"闪电标"的出现.除了改造方面的问题,MIP项目组被问到最多的就是:我用了wordpress,我用了织 ...

  9. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  10. 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送

    微信支付之微信模板消息推送                    今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...

随机推荐

  1. Excel的读取和保存(POI)

    示例 Excel文件: 数据读取: 保存路径: Jar包准备 下载地址: 链接:https://pan.baidu.com/s/1RZAwEsFwjKMlnYYGwHMfaA 提取码:h9mj 文件上 ...

  2. 20190404-transition、transform转换、animation、媒体查询

    目录 1.transition过渡 1.1简写:transiton:transition-property | transition-duration | transition-timing-func ...

  3. CSS实现无外边框列表效果

    方法一:使用外层容器切割 给每一个 li 设定右边框和下边框线 把ul放置在一个外层div中,设定div的宽高,通过overflow:hidden将一部分li的边框隐藏 此方法只需要计算父容器的宽高, ...

  4. 啰嗦的 java,简洁的 lombok —— lombok 的使用及简单实现单例模式注解

    lombok 是什么? lombok 是一个非常神奇的 java 类库,会利用注解自动生成 java Bean 中烦人的 Getter.Setting,还能自动生成 logger.ToString.H ...

  5. Java中单例模式的几种实现

    目录 懒汉式单例 简单版本 synchronized版本 双重检查(Double-Check)版本 volatile 饿汉式单例 实现1 其他实现方式 静态内部类-Effective Java 枚举- ...

  6. MyDAL - 快速使用

    索引: 目录索引 一.安装 在 VS 中执行一下 package 命令: PM> Install-Package MyDAL 二.API-快速使用 1.命名空间,只需: using MyDAL; ...

  7. Neo4j 全文检索

    全文检索基本概念 搜索 搜索这个行为是用户与搜索引擎的一次交互过程,用户需要找一些数据,他提供给搜索引擎一些约束条件.搜索引擎通过约束条件抽取一些结果给用户 搜索引擎 搜索引擎存在的目的是存储,查找和 ...

  8. 记录一次Orthanc dicom数据异常手动修复

    问题复现场景 同一个StudyInstanceUID,对应两个不同的PatientID. 通俗讲,原本是一个病人的一次影像,却割裂成两个病人的影像,虽然两个病人不影响系统数据,但是同一个Study分别 ...

  9. maven项目更换本地仓库

    由于电脑重装系统更换原来maven项目的本地仓库 以前的仓库位置如图 需要更换的仓库位置 更换步骤如下: 更换后:

  10. 【记录】使用在线KMS激活win10系统

    摘要 网上一些激活工具可能捆绑了木马.病毒.使用激活工具有风险.使用在线KMS来激活系统则没有这个风险.(自测至发布日期仍然可用) (有能力的请支持正版windows系统) 将kms服务器地址设置为k ...