2-SAT

给定一个布尔方程,判断是否存在一组布尔变量的真值指派使整个方程为真的问题,被称为布尔方程的可满足性问题(SAT)。如果合取范式的每个子句中的文字个数都不超过两个,那么对应的SAT问题又称为2-SAT问题。(具体例子看代码)

利用强连通分量分解点击打开链接,可以在布尔公式子句数的线性时间内解决2-SAT问题。首先,把每个子句(a∨b)改写成等价形式(¬a=>b∧¬b=>a),这样就把原布尔公式以=>关系为边建立有向图。此时,显然该图中同一个强连通分量所含布尔值均相同。如果存在某个布尔变量x,¬x均在同一个强连通分量中,则显然无法令整个布尔公式的值为真。反之,如果不存在这样的布尔变量,那么对于每个布尔变量x,x所在的强连通分量的拓扑序在¬x所在的强连通分量之后<=>x为真


代码:

int main()
{
          //布尔公式为(a∨¬b)∧(b∨c)∧(¬c∨¬a)时
          //构造6个顶点,分别对应a,b,c,¬a,¬b,¬c
          V=6;
          
          //a∨¬b转成¬a=>b∧b=>a
          add_edge(3,4);//从¬a连一条到¬b的边
          add_edge(1,0);//从b连一条到a的边
          //同上
          add_edge(4,2);//略
          add_edge(5,1);//略
          //同上
          add_edge(2,3);//略
          add_edge(0,5);//略
          
          //进行强连通分量分解
          scc();
          
          //判断是否可满足
          for(int i=0;i<3;i++)
          {
                   if(cmp[i]==cmp[3+i])
                   {
                              printf("NO");
                              return 0;
                   }
           }
           
          //如果可满足,则给出一组解
          printf("YES\n");
          for(int i=0;i<3;i++)
                     if(cmp[i]>cmp[3+i])
                                  printf("true\n");
                     else
                                  printf("false\n");
            
           return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值