引入:

相信大家都了解过差分约束系统。差分约束系统的大体意思就是给出一些有某种关系的变量,问你是否有某种赋值使得这些关系全部成立

其实\(2-SAT\)的题目描述和这个很像(虽然解法不一样)

那么\(2-SAT\)到底是什么呢?

首先,把\(2\)和\(SAT\)拆开。\(SAT\) 是 \(Satisfiability\) 的缩写,意为可满足性。即一串布尔变量,每个变量只能为真或假。要求对这些变量进行赋值,满足布尔方程(摘自\(Anguei\)的题解)

通俗一点来说,就是有\(n\)个bool变量\(x_1\)~\(x_n\)有\(m\)个位运算的表达式(只有两个变量),求是否有一种方法使得\(m\)个表达式都成立

\[\
\]

例题

洛谷P4782

题目背景

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的更多相关文章

  1. 【WebApi系列】浅谈HTTP

    [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi如何传递参数 [04]详解WebApi测试和PostMan [05]浅谈WebApi Core ...

  2. 【WebApi系列】浅谈HTTP在WebApi开发中的运用

    WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...

  3. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  4. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  5. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  6. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  7. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  8. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  9. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  10. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

随机推荐

  1. N1试卷常考词汇总结

    免れる まぬがれる 免去,幸免 軽率 けいそつ 轻率,草率 捩れる ねじれる 拧劲儿,扭歪,弯曲 裂ける さける 裂开,破裂 避ける さける 躲避,避开 つまむ 挟,捏,掐 追及 ついきゅう 追上.追 ...

  2. Spring Boot 实际操作

    1.什么是springboot 2.springboot的很多默认编码方式都是utf-8,真是福利啊. 3.spring boot如何启动和访问和MocMvc测试 4.开发环境的调试热启动 5.app ...

  3. Windwos Java‘bat 环境变量配置脚本

    @echo off echo 正在设置Java环境变量 pause wmic ENVIRONMENT create name="JAVA_HOME",username=" ...

  4. 更改命令行,完全显示hostname

    刚装完一台新服务器,想让命令行的能显示全部的hostname,查阅资料后,将$PS1的参数修改即可 1,echo $PS1 2,将其中的/h换成/H即可 3,我是在/etc/profile中加了一行 ...

  5. 《Maven 实战》笔记之setting.xml介绍

    maven是什么?有什么用? Maven是一个跨平台的项目管理工具,主要服务于Java平台的项目构建,依赖管理和项目信息管理.项目构建包括创建项目框架.清理.编译.测试.到生成报告,再到打包和部署,项 ...

  6. php页面禁用错误报告

    //禁用错误报告 error_reporting(0);#or ini_set("display_errors","Off"); //开启错误报告 ini_se ...

  7. 多项式FFT/NTT模板(含乘法/逆元/log/exp/求导/积分/快速幂)

    自己整理出来的模板 存在的问题: 1.多项式求逆常数过大(尤其是浮点数FFT) 2.log只支持f[0]=1的情况,exp只支持f[0]=0的情况 有待进一步修改和完善 FFT: #include&l ...

  8. http协议和i/o模型

    http协议----基于请求报文和响应报文完成一次http事务 应用层协议格式有两种: 文本(开发容易,但交互解析困难如http smtp),二进制(交互解析容易,但理解起来困难memocache) ...

  9. 2019年11月18日 JAVA期中考试 增删改查

    一.题目 石家庄铁道大学 青年志愿者服务网(20分)   1.项目需求: 为了适应社会主义市场经济发展的需要,推动青年志愿服务体系和多层次社会保障体系的建立和完善,促进青年健康成长,石家庄铁道大学急需 ...

  10. 基于Python原生asyncio模块对DNS正向和反向的解析

    一.正向解析:域名解析IP地址 import asyncio import socket domains = [ ('www.baidu.com', 'https'), ('cn.bing.com', ...