2-SAT问题
这个东西原来你咕日报见过一次 学了一半咕掉了
没想到模拟出了一道www
那么就来填个坑好辽
那么2-SAT是什么?
luogu模板题
有n个布尔变量\(x_1~x_n\),另有m个需要满足的条件,每个条件的形式都是“\(x_i\)为true/false或\(x_j\)为true/false”。比如“\(x_1\)为真或\(x_3\)为假”、“\(x_7\)为假或\(x_2\)为假”。2-SAT 问题的目标是给每个变量赋值使得所有条件得到满足。
\(1 \leq n,m \leq 10^6\)
这个东西怎么做?
这些要求都是这样的形式 "a为真或b为真"
ps.这里的a, b是指一个事件 比如"\(x_i\)的值为0"
"或"这个东西是非常不好控制的
那如果我们把这句话变成
"a为假则b必须为真","b为假则a必须为真"呢?
是不是看起来有了点思路?没有
我会暴力!
这个时候我们可以枚举每个数为真或者为假
如果要求字典序最小方案的话据说只能这么做了
然而这并不是个多项式算法
并且SAT问题已经被证明是NP完全的就是说只能暴力
要是这个时候你觉得上了假车 很正常 但不要走啊喂
我会tarjan!
我们或许可以试着建一波图
把每个数拆成两个点 \(x_i^0\) 和 \(x_i^1\)
表示\(x_i\)取0或1
那么对于一个条件
比如题干中的“\(x_1\)为真或\(x_3\)为假”
我们可以连边(\(x_1^0, x_3^0\)),(\(x_3^1, x_1^1\))
(u, v)表示,满足u就必须满足v
很明显我们连的边都具有对称性
也就是每次都对两组角标相同的点 连两条对称的边
接下来 我们把这张图用tarjan缩点
然后做第一次判定
如果相同角标的点\(x_i^0, x_i^1\)出现在一个scc里,那么无解
如果有这种情况出现的话 说明x_i等于1之后经过一系列推导发现他还要等于0
显然是不可能的
如果没有这种情况的话 我们把缩点后的图拓扑排序
从外向内选点 如果一个点被选了 说明它代表的事件发生
即\(x_i^0\)被选了说明\(x_i\)等于0
在这同时我们把\(x_i^1\)打上标记
一组构造就okk啦
wait!万一有矛盾怎么办?万一我选了一个点,走着走着又遇到了自己的相反情况怎么办?
不过不用担心,这是不存在的 证明可以看这个由对称性解2-SAT问题
现在你可以感性理解2-SAT了。。
来看几道例题?
刚刚那道模板题
[HNOI2010]平面图判定
这道题是假的。。
和平委员会
又是板子题(论文题【雾
推荐blog