简介

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)\), 但是多数情况跑不满.

代码

  1. //任意解
  2. int chos[nsz];
  3. int dfn[nsz*2],pd=0,low[nsz*2],inscc[nsz*2],ps=0;
  4. int stk[nsz*2],top=0,vi[nsz*2];
  5. void tarj(int p){
  6. dfn[p]=low[p]=++pd;
  7. stk[++top]=p,vi[p]=1;
  8. for(auto v:edge[p]){
  9. if(dfn[v]==0){
  10. tarj(v);
  11. low[p]=min(low[p],low[v]);
  12. }
  13. else if(vi[v])low[p]=min(low[p],dfn[v]);
  14. }
  15. if(low[p]==dfn[p]){//scc
  16. ++ps;
  17. int v;
  18. do{
  19. v=stk[top];
  20. inscc[v]=ps,vi[v]=0,--top;
  21. }while(v!=p);
  22. }
  23. }
  24. bool sat2(){//toefl ielts sat
  25. rep(i,2,n*2+1)if(dfn[i]==0)tarj(i);
  26. rep(i,1,n){
  27. if(inscc[i<<1]==inscc[i<<1|1])return 0;//no solution
  28. chos[i]=inscc[i<<1|1]<inscc[i<<1];
  29. }
  30. return 1;
  31. }

[模板] 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. Asp.Net Core微服务初体验

    ASP.Net Core的基本配置 .在VS中调试的时候有很多修改Web应用运行端口的方法.但是在开发.调试微服务应用的时候可能需要同时在不同端口上开启多个服务器的实例,因此下面主要看看如何通过命令行 ...

  2. SmartSql Map

    SmartSqlMap 属性 说明 Scope 域,用于SqlMap定义Sql声明范围 Statement标签 属性 说明 Id 唯一性编号 Cache 缓存策略编号,引用自Cache标签 State ...

  3. electron开发客户端注意事项(兼开源个人知识管理工具“想学吗”)

    窗口间通信的问题 electron窗口通信比nwjs要麻烦的多 electron分主进程和渲染进程,渲染进程又分主窗口的渲染进程和子窗口的渲染进程 主窗口的渲染进程给子窗口的渲染进程发消息 subWi ...

  4. [SpringBoot guides系列翻译]通过JDBC和Spring访问关系数据库

    原文 参考链接 hikaricp Spring Boot JDBC Starter Spring Boot Starter Parent h2 database introduction Autowi ...

  5. java基础(十)-----Java 序列化的高级认识

    将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口,使用 ...

  6. C#复制文件全代码--供参考

    private void button1_Click(object sender, EventArgs e) { //创建文件对象 FileInfo fi = null; //实例化打开文件对话框 O ...

  7. 杭电ACM2018--母牛的故事

    母牛的故事 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  8. [TCP/IP] 网络层-抓包分析IP数据包首部

    ip数据包的结构:首部+数据部分 1.版本(v4或者v6)+首部长度(固定的20字节,所以就没有)+区分服务优先级(我的例子是 assured forwarding 31 0x1a 26,保证转发) ...

  9. java的设计模式 - 静态工厂方法

    静态工厂方法,也不知道为何叫这个名字.其实也就是一个静态函数,可以替代构造函数用.大名鼎鼎的 guava 就大量使用这种模式,这是非常有用的模式. 比如是 Integer i = Integer.va ...

  10. 利用nginx 反向代理解决跨域问题

    说到nginx,不得不说真的很强大,也带来很多便利用于解决一些头疼的难题. 一般来说可以用来做:静态页面的服务器.静态文件缓存服务器.网站反向代理.负载均衡服务器等等,而且实现这一切,基本只需要改改那 ...