【学习笔记】 2-SAT问题
Algorithm Description
\(2-SAT\)问题就是给定一串布尔变量,每个变量只能为真或假。
要求对这些变量进行赋值,满足布尔方程。
会有一些形如 \(x_1||x_2\) 或者 \(x_5||(!x_6)\) 的条件
所谓布尔方程就是赋值之后满足所有的条件
首先扯一句,如果这个条件变成三或者三以上个\(x\)相关的了,就只能\(2^n\)枚举了
(好像是 \(N-SAT\) 问题是 \(NP\) 完全的)
然后我们思考如何求解这样的问题
前人告诉我们,可以把这些变量转移到图上进行操作
\]
首先拆点: \(i->i\) 同时 \((!i)->i+n\)
然后我们我们考虑建图的时候
对于每一个条件: \(a||b\) ,连上 \((!a)->b\) 和 \((!b)->a\) 的两条有向边
这里可以理解成【\(b\) 假则 \(a\) 必须真,\(a\) 假则 \(b\)必须真】
考虑 \(tarjan\) 求一波强连通分量,如果有 \(scc[i]==scc[i+n]\) 直接无解
显然真假是不一样的(就是不能赋相同的值)
\]
如果要跑方案,就直接输出\([scc[i]<scc[i+n]]\) 就好
例题
由于实在是模板题(不知为啥当时放这么一个纯板子……),就不写了
Code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=4e6+10;
int n,m,a,b,x,y,tim,top,tot,cnt;
int dfn[N],low[N],st[N],vis[N],scc[N],head[N];
struct node{int to,nxt;}e[N];
inline void add(int u,int v){e[++cnt].nxt=head[u],e[cnt].to=v; head[u]=cnt; return ;}
inline void tarjan(int u,int fa)
{
dfn[u]=low[u]=++tim; st[++top]=u; vis[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int t=e[i].to; if(t==fa) continue;
if(!dfn[t]) tarjan(t,u),low[u]=min(low[u],low[t]);
else if(vis[t]) low[u]=min(low[u],dfn[t]);
}
if(dfn[u]==low[u])
{
tot++; while(st[top]!=u) scc[st[top]]=tot,vis[st[top--]]=0;
scc[st[top]]=tot; vis[st[top--]]=0;
}
return ;
}
signed main()
{
n=read(); m=read();
for(int i=1;i<=m;++i)
{
a=read(); x=read(); b=read(); y=read();
if(!x&&!y) add(a+n,b),add(b+n,a);
if(!x&&y) add(a+n,b+n),add(b,a);
if(x&&!y) add(a,b),add(b+n,a+n);
if(x&&y) add(a,b+n),add(b,a+n);
}
for(int i=1;i<=2*n;++i) if(!dfn[i]) tarjan(i,0);
for(int i=1;i<=n;++i)
{
if(scc[i]==scc[i+n]) return puts("IMPOSSIBLE"),0;
}
puts("POSSIBLE"); for(int i=1;i<=n;++i) printf(scc[i]>scc[i+n]?"1 ":"0 ");
return 0;
}
}
signed main(){return yspm::main();}
瞎看吧,这个 \(add\) 压行有点严重了,没去格式化 \(2333\)
【学习笔记】 2-SAT问题的更多相关文章
- <老友记>学习笔记
这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...
- OGG学习笔记02-单向复制配置实例
OGG学习笔记02-单向复制配置实例 实验环境: 源端:192.168.1.30,Oracle 10.2.0.5 单实例 目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1. ...
- python数据分析入门学习笔记
学习利用python进行数据分析的笔记&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据分 ...
- 【MarkMark学习笔记学习笔记】javascript/js 学习笔记
1.0, 概述.JavaScript是ECMAScript的实现之一 2.0,在HTML中使用JavaScript. 2.1 3.0,基本概念 3.1,ECMAScript中的一切(变量,函数名,操作 ...
- Linux 学习笔记之超详细基础linux命令 Part 13
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 12---------------- ...
- Linux 学习笔记之超详细基础linux命令 Part 8
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 7----------------- ...
- Deep learning with Python 学习笔记(5)
本节讲深度学习用于文本和序列 用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一 ...
- 【Redis】命令学习笔记——字符串(String)(23个超全字典版)
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 本篇基于redis 4.0.11版本,学习字符串( ...
- programming-languages学习笔记--第3部分
programming-languages学习笔记–第3部分 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src ...
- 学习笔记 - 2sat
学习笔记 - 2sat 决定重新启用Markdown--只是因为它支持MathJax数学公式 noip考完,既轻松又无奈,回来慢慢填坑 这篇博客也是拖了好久,通过kuangbin的博客才弄懂2-sat ...
随机推荐
- OC Swift混编-Swift.h File not found
https://www.jianshu.com/p/f860fe1718ca 2016.09.13 11:53* 字数 266 阅读 1935评论 1喜欢 1 今天碰到个神坑,本人项目是OC项目,最近 ...
- 多线程开发之GCD
简介GCD本身是苹果公司为多核的并行运算提出的解决方案.GCD在工作时会自动利用更多的处理器核心,以充分利用更强大的机器.GCD是Grand Central Dispatch的简称,它是基于C语言的. ...
- LeJOS下eclipse通过USB连接EV3
适用情况:在eclipse安装好LeJOS插件后,再通过USB连接EV3. 第一:更新驱动 在<设备管理器-网络适配器>下更新RNDIS/Ethernet Gadget,电脑需要先连接EV ...
- DRF框架之序列化器初体验
首先,我们需要明白序列化和反序列化的过程指的是什么. 序列化操作:将模型数据 ---> 字典数据 --->JSON数据(响应JSON数据的操作) 反序列化操作:将JSON数据 ---> ...
- Java中Scanner类在nextInt()后无法输入nextLine()的问题
首先,Scanner是一个扫描器,它扫描数据都是去内存中一块缓冲区中进行扫描并读入数据的,而我们在控制台中输入的数据也都是被先存入缓冲区中等待扫描器的扫描读取.这个扫描器在扫描过程中判断停止的依据就是 ...
- Social LSTM 实现代码分析
----- 2019.8.5更新 实现代码思维导图 ----- ----- 初始原文 ----- Social LSTM最早提出于文献 "Social LSTM: Human Traject ...
- UVALive 3704 细胞自动机 矩阵快速幂
是时候要做做数学类的题目了 这属于比较简单的矩阵快速幂了,因为有个已知的矩阵循环的结论,所以为了节约时空,只需要保留一行即可,这个稍微有点难写,也不是难写,主要是注意细节.其他的矩阵快速幂一下即可 # ...
- 四、python杂项
一.pycharm单行和多行注释快捷键 多行注释就一个组合键:选中+Ctrl+/
- Jenkins 插件中心国内镜像源发布
以下文章来源于Jenkins,作者LinuxSuRen Jenkins 社区的网络基础设施都是架设在国外的服务器上,而且,并没有在国内有 CDN 或者负载均衡的配置.对所有的 Jenkins 用户而言 ...
- SQL基础教程(第2版)第3章 聚合与排序:3-1 对表进行聚合查询
3-1 对表进行聚合查询 ● 使用聚合函数对表中的列进行计算合计值或者平均值等的汇总操作.● 通常,聚合函数会对NULL以外的对象进行汇总.但是只有COUNT函数例外,使用COUNT(*)可以查出包含 ...