【学习笔记】 2-SAT问题

Description

2SAT问题就是给定一串变量,每个变量只能为真或假。

要求对这些变量进行赋值,满足方程所代表的限制条件,2sat 问题中的限制是只与两个变量有关的,形如 $x_1 || x_2 ,x_1 && (!x_2)$

如果这个条件变成三或者三以上个x相关的了,就只能2n枚举了,即 NSAT 问题是 NP 完全

Solution

首先将每个点拆成两个表示其为真或者为假,这里使用 i 表示这个点真点,i 表示假点

问题中的图上的每条边 (u,v) 表示如果 u 所代表的情况发生了,v 所代表的情况也要发生,举例而言即形如 x||y 的限制 则连 (x,y),(y,x) 即如果 x 假了则 y 必须真

而题目中的限制也常可以表示成或而不是与的形式,建图时另外一个需要注意的点就是连接表示逆否命题的边

之后 tarjan 求强连通分量,如果有 scc[i]==scc[i+n] 则无解,原因是同一个强连通分量里面的点表示一个情况的并集,一个点的真假性是唯一的

对于求解 bool 方程每个变量的解,结论是 x_i=[scc[i]<scc[i+n]]

如果 xi 可以到达 xi 但是反向不行,那么只能选择 xi,也就是其所在的强连通分量在拓扑序上排名较后的一个

这时候可以踩在巨人 tarjan 的肩膀上:使用 scc 序是拓扑序的逆序这一结论得到答案

例题

NEERC2016 Binary Code

前后缀优化建图+ 2sat 模板题,在 这篇博客 中已经有写到

JSOI2019 精准预测

(其实写这篇博客就是为了写这题题解)

将每个火星人在每个时间存在与否建立 2×n(T+1) 个点,根据实际含义,每个人本身在 i 时刻存活则在 i1 时刻存活,在 i 时刻死亡则在 i+1 时刻死亡

再根据实际含义,对于操作一,如果 yi+1 存活则 xi 存活,也要连逆否命题

对于操作二,yi 时刻存活则对应 xi 时刻死亡,也不要忘记连逆否命题

乍一看这点数很合理,已经降到 4m+2n 了,但是还能再少:真的有必要在 i/i+1 时刻给 y 建两个点吗?

其实并不需要,站到统计答案的角度看,我们只关注在 T+1 时刻的生死,具体是什么时候死的不重要

只存每个点作为 x 时刻的生死点和 T+1 时刻的生死点,作为 y 时可以 lower_bound 下一个作为 x 的时候

最后是统计答案,不能同生的是自己生的后继中它人死,和那些自己生的后继中有自己死的点,注意去重

这明显是一个 DAG 上可达点统计问题,使用 bitset 优化可以做到 Θ(nmω)

posted @   没学完四大礼包不改名  阅读(180)  评论(3编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示