2-SAT 学习笔记

2-SAT 学习笔记

P4782 【模板】2-SAT

2-SAT 问题模型:构造 bool 变量 \(x_1,x_2...x_n\),使得满足一些限制一对 \(x_1\)\(x_2\) 取值的条件合法。

很显然根据 Floyd 传递闭包可以做到 \(O(n^3+m)\),但不太行。

\(O(n+m)\) 的做法,发现对于每个条件是要我们选择一种取值(选择就很缥缈),我们考虑转换为一些定性的限制条件(更为直接一些)。

因为每个点只有两种取值,所以对每个限制考虑分类讨论,拿 \(x_7\) 为假或 \(x_2\) 为假举例。

如果 \(x_7\) 取假,那么对 \(x_2\) 没有限制。如果 \(x_7\) 取真,那么 \(x_2\)必须取假。所以把他转换到图论模型,对 \(x_2\)\(¬x_7\) 连边。同理,对 \(x_7\)\(¬x_2\) 连边,边的含义就是如果取了 \(u\),那就必须取 \(v\)

考虑无解的情况,很显然,如果一个 \(x_i\) 我们钦定它是 \(1\),但是发现推了一圈回来以后发现是 \(0\),那就产生了矛盾,那说明 \(x_i=1\) 是不可取的。

回到我们建出来的图上,实际就是如果 \(x_i\) 可以走到 \(¬x_i\)\(¬x_i\) 能走到 \(x_i\) 那就是无解。

容易发现,他们是在一个强连通分量里面的,因为他们可以互相抵达。

所以我们只用对建出来的图跑一个缩点即可,如果 \(x_i\)\(¬x_i\) 在一个强连通分量里面,那必然无解。

那考虑有解的情况的构造。

缩完了点以后,我们发现,拓扑序小的点一定是可以一层一层往里面推出来拓扑序大的点的答案,反之不行。

原因是如果你选择了拓扑序大的话,拓扑序小的点所在的那个环,其实就不能被更新到了。

但是 Tarjan 搞出来的拓扑序恰好的倒序的,因为他是个 dfs,是自下而上的找到 SCC,所以标号大的才是拓扑序小的点。

具体实现是要开 \(2n\) 个点来表示 \(0/1\) 的取值。

如果是 \(a \oplus b\),那显然是如果 \(a\) 取了 \(1\)\(b\) 只能取 \(0\),显然 \(a\)\(¬b\) 连边, \(b\)\(¬a\) 连边。

如果是 $a \land b $,如果 \(a\) 取了 \(0\),必然矛盾,所以 \(¬a\)\(a\) 连边直接让他矛盾掉。

在实际问题里面,可以转换成一个点的选/不选成为 \(0/1\) 的变量,单独对每个点和每个限制考虑,这是两种不一样的思路。

posted @   June_Failure  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示