浅谈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特殊符号又可 ...
随机推荐
- N1试卷常考词汇总结
免れる まぬがれる 免去,幸免 軽率 けいそつ 轻率,草率 捩れる ねじれる 拧劲儿,扭歪,弯曲 裂ける さける 裂开,破裂 避ける さける 躲避,避开 つまむ 挟,捏,掐 追及 ついきゅう 追上.追 ...
- Spring Boot 实际操作
1.什么是springboot 2.springboot的很多默认编码方式都是utf-8,真是福利啊. 3.spring boot如何启动和访问和MocMvc测试 4.开发环境的调试热启动 5.app ...
- Windwos Java‘bat 环境变量配置脚本
@echo off echo 正在设置Java环境变量 pause wmic ENVIRONMENT create name="JAVA_HOME",username=" ...
- 更改命令行,完全显示hostname
刚装完一台新服务器,想让命令行的能显示全部的hostname,查阅资料后,将$PS1的参数修改即可 1,echo $PS1 2,将其中的/h换成/H即可 3,我是在/etc/profile中加了一行 ...
- 《Maven 实战》笔记之setting.xml介绍
maven是什么?有什么用? Maven是一个跨平台的项目管理工具,主要服务于Java平台的项目构建,依赖管理和项目信息管理.项目构建包括创建项目框架.清理.编译.测试.到生成报告,再到打包和部署,项 ...
- php页面禁用错误报告
//禁用错误报告 error_reporting(0);#or ini_set("display_errors","Off"); //开启错误报告 ini_se ...
- 多项式FFT/NTT模板(含乘法/逆元/log/exp/求导/积分/快速幂)
自己整理出来的模板 存在的问题: 1.多项式求逆常数过大(尤其是浮点数FFT) 2.log只支持f[0]=1的情况,exp只支持f[0]=0的情况 有待进一步修改和完善 FFT: #include&l ...
- http协议和i/o模型
http协议----基于请求报文和响应报文完成一次http事务 应用层协议格式有两种: 文本(开发容易,但交互解析困难如http smtp),二进制(交互解析容易,但理解起来困难memocache) ...
- 2019年11月18日 JAVA期中考试 增删改查
一.题目 石家庄铁道大学 青年志愿者服务网(20分) 1.项目需求: 为了适应社会主义市场经济发展的需要,推动青年志愿服务体系和多层次社会保障体系的建立和完善,促进青年健康成长,石家庄铁道大学急需 ...
- 基于Python原生asyncio模块对DNS正向和反向的解析
一.正向解析:域名解析IP地址 import asyncio import socket domains = [ ('www.baidu.com', 'https'), ('cn.bing.com', ...