zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:

    守护线程
    下载图片
    多线程
    self的作用
    设置项目地址环境
    对象 类
    ValueError: urls must start with a leading slash
    mock挡板接口开发
    K&R——第五章 指针与数组
  • 原文地址:https://www.cnblogs.com/hjmmm/p/10670760.html
Copyright © 2011-2022 走看看