一个不错的2-SAT文章:传送门
问题初入
什么是2-SAT
SAT是适定性(Satisfiability)问题的简称 。一般形式为k-适定性问题,简称 k-SAT。
首先,把「2」和「SAT」拆开。SAT 是 Satisfiability 的缩写,意为可满足性。即一串布尔变量,每个变量只能为真或假。要求对这些变量进行赋值,满足布尔方程。
如何实现2-SAT
一道例题:洛谷P4782 2-SAT例题
首先将每个or的问题转换成假->真问题
然后跑缩点
因为缩点中跑出来的强连通分量的拓扑序已经在过程中求出(虽然是逆序),然后再判断一遍
当 x 所在的强连通分量的拓扑序在 ¬x 所在的强连通分量的拓扑序之后取 x 为真 就可以了。在使用 Tarjan 算法缩点找强连通分量的过程中,已经为每组强连通分量标记好顺序了不过是反着的拓扑序。
上代码
#include<bits/stdc++.h>
#define re register
#define ll long long
using namespace std;
inline int read()
{
ll k=1,sum=0;
char c=getchar();
for(;c<'0' || c>'9';c=getchar()) if(c=='-') k=-1;
for(;c>='0' && c<='9';c=getchar()) sum=sum*10+c-'0';
return sum*k;
}
const int N=1e6+10;
int n,m;
struct Edge{
int to,nxt;
};
int head[N<<1],cnt;
Edge edge[N<<2];
inline void Add(int x,int y){
edge[++cnt].to=y;edge[cnt].nxt=head[x];head[x]=cnt;
}
int dfn[N<<1],ins[N<<1],color[N<<1],low[N<<1],col;
bool vis[N<<1];
int id;
stack<int> S;
inline void Tarjan(int x){
S.push(x);
ins[x]=1;
dfn[x]=low[x]=++id;
for(re int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(!dfn[y]){
Tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(ins[y]) low[x]=min(low[x],low[y]);
}
if(low[x]==dfn[x]) {
re int k=-1;++col;
while(k!=x){
k=S.top();S.pop();
ins[k]=0;
color[k]=col;
}
}
}
int main()
{
n=read();m=read();
for(re int k=1;k<=m;++k){
int i=read(),a=read(),j=read(),b=read();
Add(i+n*(a&1),j+n*(b^1));
Add(j+n*(b&1),i+n*(a^1));
}
for(re int i=1;i<=n<<1;++i){
if(!dfn[i]) Tarjan(i);
}
for(re int i=1;i<=n;++i)
if(color[i]==color[i+n]){
puts("IMPOSSIBLE");
return 0;
}
puts("POSSIBLE");
for(re int i=1;i<=n;++i) {
cout<<((color[i]<color[i+n])?1:0)<<" ";
}
return 0;
}
2-SAT问题学习笔记+例题[洛谷P4792]的更多相关文章
-
倍增求LCA学习笔记(洛谷 P3379 【模板】最近公共祖先(LCA))
倍增求\(LCA\) 倍增基础 从字面意思理解,倍增就是"成倍增长". 一般地,此处的增长并非线性地翻倍,而是在预处理时处理长度为\(2^n(n\in \mathbb{N}^+)\ ...
-
dp凸优化/wqs二分学习笔记(洛谷4383 [八省联考2018]林克卡特树lct)
qwq 安利一个凸优化讲的比较好的博客 https://www.cnblogs.com/Gloid/p/9433783.html 但是他的暴力部分略微有点问题 qwq 我还是详细的讲一下这个题+这个知 ...
-
JavaEE精英进阶课学习笔记《博学谷》
JavaEE精英进阶课学习笔记<博学谷> 第1章 亿可控系统分析与设计 学习目标 了解物联网应用领域及发展现状 能够说出亿可控的核心功能 能够画出亿可控的系统架构图 能够完成亿可控环境的准 ...
-
【算法学习】【洛谷】树链剖分 &; P3384 【模板】树链剖分 P2146 软件包管理器
刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...
-
【算法学习】【洛谷】cdq分治 &; P3810 三维偏序
cdq是何许人也?请参看这篇:https://wenku.baidu.com/view/3b913556fd0a79563d1e7245.html. 在这篇论文中,cdq提出了对修改/询问型问题(Mo ...
-
【做题笔记】洛谷P1506 拯救oibh总部
跑一遍染色法,最后判断哪些位置没被染色即可 一些技巧: 为了判断方便,把字符转换成 int 型的数字. 注意边界问题 详细解释见代码 #include <iostream> #includ ...
-
【做题笔记】洛谷P1036 选数
作为一个 DFS 初学者这题真的做得很惨...其实窝学 DFS 一年多了,然后一开始就学不会最近被图论和数据结构打自闭后才准备好好学一学233 一开始,直接套框架,于是就有 #include < ...
-
【做题笔记】洛谷P1955[NOI2015]程序自动分析
第一道蓝题祭- 注意到本题中判断的是下标,即,并不是真的判断 \(i\) 是否等于 \(j\) 显然考虑并查集,把所有标记为"相等"的数放在一个集合里,然后最后扫一遍每个数,如果有 ...
-
【做题笔记】洛谷P1002过河卒
虽说是 dp 入门题,但还是有很多细节需要注意 如果设 \(f_{x,y}\) 为目标地点为 \((x,y)\) 时走的种数,那么答案就是 \(f_{n,m}\) 在不考虑那只讨厌的马的情况下,对于任 ...
随机推荐
-
Linux命令学习总结:rmdir
命令简介: 该命令用用来删除空目录,如果目录非空,则会出现错误.可以使用rm删除目录中的文件后,使用rmdir删除目录.也可以使用rm -rf替代rmdir命令.这是一个非常简单的命令. 命令语法 ...
-
mui问题
2016.7.27 1.当你的html不在文件夹的时候 引路径就不要加../ 2.当用svn提交代码的时候要先右键项目->版本管理->与资源库同步,查看你的修改的地方和原来部署上去的文 ...
-
cad中关于点样式点的绘制
点样式 从0开始, 默认的就是0 0= 一个小点; 1= 空的, 什么都不显示; 2= +加号; 3= X 叉号 设置点样式的命令是: pdmode: 可以假设认为是: point default m ...
-
CSS基础汇总
1. css的出现是为了是内容和表现分离.分为三种: 内联:不推荐 嵌入:没有利用浏览器缓存机制. 外联: 2. css优先级:①id优先级高于class②后面的样式覆盖前面的③指定的高于继承④行内样 ...
-
Git 分布式版本管理
Git是分布式版本控制系统,我们常用的版本控制工具还有SVN.这里就得区分下什么是分布式版本控制系统,什么是集中化的版本控制系统. 集中化的版本控制系统 集中化的版本控制系统( Centralized ...
-
黄聪:PHP 免费获取手机号码归属地(转)
一.淘宝网API API地址: http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=15850781443 参数: tel:手机号码 返回 ...
-
adb 获取手机值
获取手机RAM值 adb shell cat /proc/meminfo 获取手机内存值 adb shell df /data
-
【Android Developers Training】 1. 创建一个Android项目工程
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
-
python3学习笔记(3)
一.内置函数补充1.callable()检测传递的参数是否可以被调用.def f1() pass可以被调用f2 = 123不可以被调用2.chr()和ord()chr()将ascii码转换成字符,or ...
-
学习笔记-C++ STL iterator与对指针的理解-20170618
vector的itrerator支持random access #include<iostream> #include<vector> using namespace std; ...