浅谈2-SAT(待续)
2-SAT问题,其实是一个逻辑互斥问题。
做了两道裸题之后仔细想来,和小时候做过的“有两个女生,如果A是女生,那么B一定不是女生。A和C性别相同,求A、B、C三人的性别。”几乎是一样的。
对于这道题我们来分析一下。
“如果A是女生,那么B一定不是女生”——A和B性别相反,假设“A为女生”为true,那么“B为女生”必定为false,于是一定有“B为男生”为true【注意是一定】。
对于这句话同理可得,假设“B为女生”为true,那么“A为男生”必定为true。
“A和C性别相同”——假设“A为女生”为true,那么“C为女生”必定为true; 假设“A为男生”为true,那么“C为男生”必定为true。
这道题的逻辑关系十分简单,我们可以肉眼看出答案,然而对于一些逻辑关系成千上万达到1E6数量的我们不能直观看出,所以针对比较复杂的情况,人力想出了列表的方法。
| A | B | C
——————————
女 | | |
——————————
男 | | |
之后对于随机选择一个格子进行假设保证不出现互斥的情况。
如何实现的?比如我在"A男"这一格打了勾,那么必定会在“B女”,“C男”打勾,发现不满足题意,再令A为女生重新打勾。
下面讨论2-SAT的算法。
先说一些概念:
一个命题:若P则Q。
它的逆否命题:若非Q则非P。
这两个是等价的(大多2-SAT图是对称的,一些不对称的图指定了某个条件的真假性)
一些“不同时为真”、“不同时为假”的逻辑关系都可以化成“若P则Q”的形式(“不同时为真”:若A为真则B为假,及其逆否命题 若B为真则A为假;若B为假则A为真,及其逆否命题 若A为假则B为真)
对于“若P则Q”,我们从P出发,连一条边到Q,代表P如果为真Q一定为真。对于所有这样的逻辑关系都建立这样的逻辑边,之后选取一个节点进行假设赋值,如果这个点无论真假都不满足条件,该问题就无解。
然后解题顺序:
1.建图(把每个点拆成点A 2*i 和点B2*i+1,对于每个点A和B必定有且仅有一个为真)
2.跑2-SAT
下面放代码模板
void _clean(){
for(int i=;i<=n*+;i++){
g[i].clear();
mark[i]=false;
}
}
bool _dfs(int u){
if(mark[u^])return false;//如果该点的对立面为真,该点必定为假
if(mark[u])return true;//如果该点之前扫过,为真,那么直接返回
mark[u]=true;//如果这个点没讨论过(A/B两点均没赋值),那么把该点赋为真
stk[++top]=u;//进栈,这个我还没能理解,不过最后满栈应该是top==n,栈里的都为真
for(int i=;i<g[u].size();i++)
if(!_dfs(g[u][i]))return false;//该点为真,那么和这个点相连的每个点全必须为真,否则返回false
return true;
}
bool _Twosat(){
_clean();
top=;
for(int i=;i<=n*+;i+=)
if(!mark[i+] && !mark[i]){//如果该点没讨论过
top=;
if(!_dfs(i)){假设A点为真失败
while(top)
mark[stk[top--]]=false;//栈里元素全出栈,并赋值为假
if(!_dfs(i+))return false;//如果假设B点为真也失败,那么无解。
}
}
return true;
}
补充:
1、2-SAT问题就是一个“不能同时为真”、“若满足状态1就必定满足状态2”的逻辑问题。这一类问题的特点大多是对于每个对象可以等价成两种互斥状态。
2、大多的2-SAT问题是对称的,即满足p->q,就一定满足-q->-p(逆否命题的互推),但也有个别例外,就是比如有一个对象与2-sat图的其他对象关联,但是题目已经决定了这个对象必须是某一个状态(不能自我假设了,这个时候可以对于这个点跑一个裸的dfs,一会儿我会讲到例题)
下边讲几道2-SAT的题目(都只讲建图不放代码了)
1、
另一篇博文里有详细题解:http://www.cnblogs.com/L-Excalibur/p/8513386.html
2、
题目链接:https://cn.vjudge.net/contest/209473#problem/K
题目大意:有一堆宇航员要去完成任务,A任务非常伟大,只有能力值大于等于平均能力值的人才能完成,B任务是普通任务,只有能力值低于平均能力值的人才会去完成,C任务不限制条件,所有能力值的人都可以做。但是这堆宇航员互相有一些憎恨关系,如果两个宇航员互相憎恨,那么就不能给他们分配同一个任务,给出一个合理方案,如果没有合理方案输出no solution。
解题思路:每个能力值大于等于平均值的人(以下简称第一类人)划分为两种状态a.选择任务A,b.选择任务C;能力值小于平均值(第二类人)划分为两种状态a.选择任务B,b.选择任务C。如果第一类人或第二类人有内部矛盾,那么如果其中一个为状态a,另一个一定为状态b(对称建图,不能同时为a和b,共四条)。如果第一类人和第二类人有矛盾,那么不能同时为b,一个为b另一个一定为a。
浅谈2-SAT(待续)的更多相关文章
- 【WebApi系列】浅谈HTTP
[01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi如何传递参数 [04]详解WebApi测试和PostMan [05]浅谈WebApi Core ...
- 【WebApi系列】浅谈HTTP在WebApi开发中的运用
WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...
- C#中,用HashTable,DataTable等复制和克隆浅谈
如有雷同,不胜荣欣,若转载,请注明 在C#中,用HashTable,DataTable等复制和克隆浅谈,下面直接看例子 HashTable ht = null; ht = new HashTable( ...
- C# 复制和克隆认识浅谈
如有雷同,不胜荣欣.若转载,请注明 在C#中,用HashTable,DataTable等复制和克隆浅谈,以下直接看样例 HashTable ht = null; ht = new HashTable( ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
随机推荐
- Java 使用 Enum 实现单例模式
在这篇文章中介绍了单例模式有五种写法:懒汉.饿汉.双重检验锁.静态内部类.枚举.如果涉及到反序列化创建对象时推荐使用枚举的方式来实现单例,因为Enum能防止反序列化时重新创建新的对象.本文介绍 Enu ...
- Python里面这些点,据说80%的新手都会一脸懵逼
Python里面这些点,据说80%的新手都会一脸懵逼 菜鸟Python 关注 2018.10.10 12:51 字数 1833 阅读 123评论 0喜欢 10 Python虽然语法简单,通俗易懂,但是 ...
- OOP的函数方法
<?php class Computer{ //我要创建一个构造方法 public function __construct(){ echo '我是比较先进的构造方法!'; //构造方法一般用于 ...
- python+正态分布+蒙特卡洛预测男女身高概率!
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...
- Scala进阶之路-面向对象编程之类的成员详解
Scala进阶之路-面向对象编程之类的成员详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala中的object对象及apply方法 1>.scala 单例对象 ...
- linux常用端口查询
0 | 无效端口,通常用于分析操作系统1 | 传输控制协议端口服务多路开关选择器2 | 管理实用程序3 | 压缩进程5 | 远程作业登录7 | 回显9 | 丢弃11 | 在线用户13 | 时间17 | ...
- bzoj千题计划277:bzoj4513: [Sdoi2016]储能表
http://www.lydsy.com/JudgeOnline/problem.php?id=4513 f[i][0/1][0/1][0/1] 从高到低第i位,是否卡n的上限,是否卡m的上限,是否卡 ...
- SQL语句(六)成批导入导出数据
(六) 成批导入导出数据 假设已经存在teaching数据库, 存在一张Student表,如图: 右键teaching->任务->导入数据 下一步->数据源(Microsoft Ex ...
- 流媒体技术学习笔记之(十一)Windows环境运行EasyDarwin
流媒体平台框架下载安装 Github下载 下载地址:https://github.com/EasyDarwin/EasyDarwin/releases 解压安装 选择Windows 安装平台的安装包( ...
- Java 多线程(Thread) 同步(synchronized) 以及 wait, notify 相关 [实例介绍]
场景描述 有一家很大的商场,在某市有几个商品配送中心,并有几家分店,这家商场经营很多的商品,平时运营情况是这样的: 根据各分店的商品销售情况,给分店配送相应需求量的商品:并上架到分店指让的位置,供客户 ...