2-SAT

我 注定摒除 所有怅惘
执 着缔造 无暇开场

我 注定离开 这个地方
动身往云间翱翔

我 生为飞蛾 天性向光
撕裂疮疤 复苏生长

我 生为凤凰 本能高唱
倔强是翅膀

——洛天依《向光》


2-SAT

算法本身很简单,难点在于建模。

所以本质上就是构造

核心的方案就是把 \(p \lor q\) 转化为 \(\neg p \to q\)\(\neg q \to p\) 这两条边,其它条件基本上都可以转化为若干个 \(p \lor q\)\(\land\) 的形式。

例如 \(p\) 成立等价于 \(p \lor p\) 可转化为 \(\neg p \to p\)

天依宝宝可爱!


洛谷 P4782

思维难度:\(\color{#FE4C61} 红\) *800

板子题。

先把每个命题拆成 \(p\)\(\neg p\),于是条件可以表示成若干个 \(p \Rarr q\) 的形式,于是这么建图。

显然如果 \(p\)\(\neg p\) 在同一个 scc 内,那么一定无解。

那么 tarjan 缩点求出拓扑序,于是在得到的 DAG 中如果前面的点为真,呢么这个点后面的所有点一定都为真。又因为 \(p\)\(\neg p\) 不能同时成立,所以总是让这两者中靠后的那个为真,靠前的那个为假一定是更优的。

可以证明这样做一定可以构造出一组合法解,看起来好像不大对,但确实是对的,虽然我不会证吧(

还有,实际上不需要显式地求出拓扑序,因为据说 tarjan 缩点后的 scc 编号就是反向的拓扑序。

注意连边的时候如果连了一条边 \(p \to q\),那么也一定要连 \(\neg q \to \neg p\)

submission

天依宝宝可爱!


洛谷 P5782

思维难度:\(\color{#FE4C61} 红\) *800

为什么要放两道一模一样的板子题()

submission

天依宝宝可爱!


洛谷 P4171

思维难度:\(\color{#FE4C61} 红\) *800

为什么要放三道一模一样的板子题()

submission

天依宝宝可爱!


洛谷 P6378

思维难度:\(\color{#FFC116} 黄\) *1500

终于不是板子题了。

显然可以暴力建图。具体地,对于原图上每条边 \(u,v\) 满足的条件是 \(u \lor v\),这个是容易的;对于一个部分 \(s\) 的所有点 \(u\),都这样建边:\(\forall _{v \in s \land v \ne u} u \to v\) 即可。

但是这样边数是 \(O(n^2)\) 的,显然不可行(不过还是可以得到 92pts 的好成绩!

然后有一个挺神的 trick,就是前缀优化建图。

现在只考虑同一部分内的点。我们新建一些点,\(p_i\) 表示 \(a_{1 \sim i}\) 中是否有关键点。于是就得到了这样的图:

然后考虑建哪些边:

  1. 首先根据 \(p\) 的定义,\(a_i \to p_i\) 这条边一定是要建的;同时对应的 \(\neg p_i \to \neg a_i\) 也要建。
  2. 然后因为是前缀,\(p_i \to p_{i+1}\) 也要建;对应 \(\neg p_{i+1} \to \neg p_i\)
  3. 因为只能选一个关键点的限制,所以 \(p_i \to \neg a_{i+1}\) 也要建;对应 \(a_{i+1} \to \neg p_i\)

得到这样一个图:

总边数为 \(2 \times (3n+m) \le 8 \times 10^6\)

\(p\) 的建立上,有一个简便方法,可以直接拿 \(p_{a_i}\) 表示 \(a_i\) 对应的前缀,这样就不需要分别算每个部分的 \(p\) 了。

感觉有时间要补一补图论建模,不过等后面吧,毕竟写 ds 已经写吐了……

submission

天依宝宝可爱!


CF568C

思维难度:\(\color{#52C41A} 绿\) *1700

思路还是比较简单的。就直接从前往后贪心,尽量让靠前的位置和给定串相同,后面尽量往小了放就可以。因为数据范围太小,所以即使每次 \(O(m)\) 跑一遍 2-SAT,总复杂度也是 \(O(nm)\) 的。

不过细节巨巨巨巨巨多。

所以放弃了,扔一个光荣的 Wrong answer on test 1 在这里吧 😃 submission

天依宝宝可爱!

posted @ 2025-08-19 09:49  little__bug  阅读(7)  评论(0)    收藏  举报