【学习笔记】 2-SAT问题
Description
问题就是给定一串变量,每个变量只能为真或假。
要求对这些变量进行赋值,满足方程所代表的限制条件, 问题中的限制是只与两个变量有关的,形如 $x_1 || x_2 x_1 && (!x_2)$
如果这个条件变成三或者三以上个相关的了,就只能枚举了,即 问题是 完全
Solution
首先将每个点拆成两个表示其为真或者为假,这里使用 表示这个点真点, 表示假点
问题中的图上的每条边 表示如果 所代表的情况发生了, 所代表的情况也要发生,举例而言即形如 的限制 则连 即如果 假了则 必须真
而题目中的限制也常可以表示成或而不是与的形式,建图时另外一个需要注意的点就是连接表示逆否命题的边
之后 求强连通分量,如果有 scc[i]==scc[i+n]
则无解,原因是同一个强连通分量里面的点表示一个情况的并集,一个点的真假性是唯一的
对于求解 bool
方程每个变量的解,结论是 x_i=[scc[i]<scc[i+n]]
如果 可以到达 但是反向不行,那么只能选择 ,也就是其所在的强连通分量在拓扑序上排名较后的一个
这时候可以踩在巨人 的肩膀上:使用 序是拓扑序的逆序这一结论得到答案
例题
NEERC2016 Binary Code
前后缀优化建图+ 模板题,在 这篇博客 中已经有写到
JSOI2019 精准预测
(其实写这篇博客就是为了写这题题解)
将每个火星人在每个时间存在与否建立 个点,根据实际含义,每个人本身在 时刻存活则在 时刻存活,在 时刻死亡则在 时刻死亡
再根据实际含义,对于操作一,如果 在 存活则 在 存活,也要连逆否命题
对于操作二, 在 时刻存活则对应 在 时刻死亡,也不要忘记连逆否命题
乍一看这点数很合理,已经降到 了,但是还能再少:真的有必要在 时刻给 建两个点吗?
其实并不需要,站到统计答案的角度看,我们只关注在 时刻的生死,具体是什么时候死的不重要
只存每个点作为 时刻的生死点和 时刻的生死点,作为 时可以 lower_bound
下一个作为 的时候
最后是统计答案,不能同生的是自己生的后继中它人死,和那些自己生的后继中有自己死的点,注意去重
这明显是一个 上可达点统计问题,使用 bitset
优化可以做到
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律