浅谈2-SAT
引入:
相信大家都了解过差分约束系统。差分约束系统的大体意思就是给出一些有某种关系的变量,问你是否有某种赋值使得这些关系全部成立
其实\(2-SAT\)的题目描述和这个很像(虽然解法不一样)
那么\(2-SAT\)到底是什么呢?
首先,把\(2\)和\(SAT\)拆开。\(SAT\) 是 \(Satisfiability\) 的缩写,意为可满足性。即一串布尔变量,每个变量只能为真或假。要求对这些变量进行赋值,满足布尔方程(摘自\(Anguei\)的题解)
通俗一点来说,就是有\(n\)个bool变量\(x_1\)~\(x_n\)有\(m\)个位运算的表达式(只有两个变量),求是否有一种方法使得\(m\)个表达式都成立
\]
例题
题目背景
2-SAT 问题 模板
题目描述
有\(n\)个布尔变量\(x_1\)~\(x_n\),另有\(m\)个需要满足的条件,每个条件的形式都是"\(x_i\)为true/false"或"\(x_j\)为true/false"。比如"\(x_1\)为真或\(x_3\)为假"、"\(x_7\)为假或\(x_2\)为假"。2-SAT 问题的目标是给每个变量赋值使得所有条件得到满足。
输入格式
第一行两个整数n和m,意义如体面所述。
接下来m行每行4个整数$ i ,a, j, b \(,表示"\)x_i\(为a或\)x_j\(为b"(\)a,b\in {0,1}$)
输出格式
如无解,输出"IMPOSSIBLE"(不带引号); 否则输出"POSSIBLE"(不带引号),下一行\(n\)个整数(\(x_1\)~\(x_n\)\(\in \{0,1\}\)),表示构造出的解。
\]
如何解决这类问题?
首先,我们发现一个变量取值的真和假是相对独立的,也就是说和他自己没有关系,只和其他变量的真假有关系
那我们不妨为每一个变量建两个节点,一个表示真,一个表示假(我这里用1n表示假,n+12n表示真)
有了点,考虑怎么连边。如果一个变量的真假能够推出另一个变量的真假,就对这两个变量对应的真假连边
比如:\(x_1\)为真或\(x_2\)为假,那么\(x_1\)的假就可以推出\(x_2\)的真,\(x_2\)的真就可以推出\(x_1\)的假
那么就把\(x_1\)对应的假节点连向\(x_2\)对应的真节点,把\(x_2\)对应的真节点连向\(x_1\)对应的假节点
如何判断有没有解?
考虑无解的情况,肯定是出现了矛盾,也就是一个点的真推出了它自己的假,或者是这个点的假推出了它自己的真。这种情况有什么特征?
发现如果是这样的话,这个点的真和假一定在相同的强连通分量里面
强联通分量?那不就是tarjan吗?
时间复杂度O(n+m)
那么怎么找出满足题意的解?
当\(x\)所在的强连通分量的拓扑序在\(\neg x\)之后时,直接取\(x\)为真就行了。tarjan算法在执行的过程中已经为每一个强连通分量标好了拓扑序(不过是和正常的拓扑序相反)
#include<bits/stdc++.h>
using namespace std;
const int N=2000050;
int head[N],ecnt;//1~n存0,n+1~2n存1
struct edge
{
int to,nxt;
}edg[N<<1];
inline void add(int u,int v)
{
edg[++ecnt].to=v;
edg[ecnt].nxt=head[u];
head[u]=ecnt;
}
int n,m;
inline void read()
{
for(int i=1;i<=m;i++)
{
int x,a,y,b;
scanf("%d%d%d%d",&x,&a,&y,&b);//建边
if(a==1&&b==1) add(x,y+n),add(y,x+n);
if(a==0&&b==1) add(x+n,y+n),add(y,x);
if(a==1&&b==0) add(x,y),add(y+n,x+n);
if(a==0&&b==0) add(x+n,y),add(y+n,x);
}
}
//tarjan
int dfn[N],low[N],in[N],s[N],scc[N],top,ind,cnt;
void tarjan(int x)
{
low[x]=dfn[x]=++ind;
s[top++]=x;
in[x]=1;
for(int i=head[x];i;i=edg[i].nxt)
{
int v=edg[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(in[v]) low[x]=min(low[x],dfn[v]);
}
if(dfn[x]==low[x])
{
cnt++;
while(s[top]!=x)
{
top--;
in[s[top]]=0;
scc[s[top]]=cnt;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
read();
for(int i=1;i<=2*n;i++)
{
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=n;i++) if(scc[i]==scc[i+n]) return cout<<"IMPOSSIBLE",0;
puts("POSSIBLE");
for(int i=1;i<=n;i++) printf("%d ",scc[i]>scc[i+n]);
}
浅谈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 ...
- 浅谈 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等,我们要满足以上所 ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Linux特殊符号浅谈
Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...
随机推荐
- Slimvoice快速而小巧
这可行吗?绝对没问题.完全加载的最大页面只有230 KB.因为所有内容都被缓存和压缩,所以随后查看的每个页面只有大约6 KB,这比我见过的具有相同功能的SPA要小得多. Slimvoice快速而小巧, ...
- 大神的JS代码风格指南
js代码风格指南:1.缩进使用空格,不要用制表符2.必须用分号3.暂时不用ES6(modules)例如export和import命令4.不鼓励(不禁止)水平对齐5.少用var 都应该使用const或者 ...
- 第十四篇 JS实现加减乘除 正则表达式
JS实现加减乘除 这节课,将会继续使用到if判断,会让同学们再看到一个新的,else if判断语句,意思是:否则如果,是基于if下的判断语句,就是说,if不成立则再来判断else if,可以这样,假如 ...
- oracle数据库连接问题org.springframework.jdbc.support.MetaDataAccessException: JDBC DatabaseMetaData method not implemented by JDBC driver - upgrade your driver...
org.springframework.jdbc.support.MetaDataAccessException: JDBC DatabaseMetaData method not implement ...
- SecureCRT 连接 Centos7.0 (NAT模式),且能连接公网。
1.打开物理主机运行-输入cmd,输入ipconfig,获取物理主机ip地址. ip:192.168.11.138 2.点击网络适配器,选择NAT模式. 3.点击Centos界面左上角-编辑-虚拟网络 ...
- Linux中的Mariadb数据库的主备
对于一个mysql服务器, 一般有两个线程来负责复制和被复制.当开启复制之后. MySQL 复制的基本过程如下: 1. Slave 上面的IO线程连接上 Master,并请求从指定日志文件的指定位置( ...
- Codeforces 991 车牌号组合数学计算
A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_bac ...
- 【LuoguP5383】[模板]普通多项式转下降幂多项式
传送门 Sol (怎么老是有人喜欢出新的多项式毒瘤板子,懒得整到一起了) 核心就是把 幂用下降幂来代替. 使用斯特林数展开幂为下降幂: \[x^n=\sum_{i=0}^n{x\choose i}i! ...
- mysql 8.0.18 mgr 搭建及其切换
mysql 8.0.18 mgr 搭建及其切换 一.系统安装包 yum -y install make gcc-c++ cmake bison-devel ncurses-devel readline ...
- 用SWPM导入SAP时因用户Culture及系统Locale引发的问题
[问题]SWPM安装SAP时因用户Culture及系统Locale引发的问题 [现象] ①IE浏览器显示空白(SWPM界面不显示) ②SAP安装时出现“Error occurs when execut ...