• [模板] 2-SAT 问题


    简介

    2-SAT (2-satisfiability) 问题形如:

    1. 给定一些变量 (x_i in {true, false});
    2. 给定一些一元/二元约束条件, 如 (x_i land lnot x_j), 利用 (land) 连接;
    3. 为每一个变量赋一个值, 满足所有约束条件.

    将第2条中的一/二元约束条件改为多元, 即为 N-SAT 问题.

    可以证明 N-SAT 问题没有多项式解法, 但 2-SAT 问题有 (O(n + m)) 的解法.

    算法

    对每个变量建立两个点: (x_i), (x_i'), 表示取真或假.

    根据约束条件建立若干条边 ((p, q)), 表示若选 (p) 则必须选 (q). (见下)

    将得到的图缩点. 若 (x_i)(x_i') 在同一个强连通分量内, 则无解.

    否则, 若 (x_i) 的所在强连通分量的拓扑序大于 (x_i'), 则选 (x_i); 否则选 (x_i').

    我们知道tarjan算法求出的强连通分量标号为强连通分量拓扑序的逆序. 因此判断 (scc_{x_i} < scc_{x_i'}) 即可.

    建边

    1. 一元逻辑
      1. (p): ((p', p));
      2. (lnot p): ((p, p')).
    2. 二元逻辑 ((p)(lnot p) 是一样的, 下面仅描述 (p) 的情况)
      1. (p ightarrow q): ((p, q)), ((q', p'));
      2. (p land q): 等价于 (p), (q);
      3. (p lor q): ((p', q)), ((q', p)) (等价于 (lnot p ightarrow q));
      4. (p oplus q): ((p, q')), ((p', q)), ((q, p')), ((q', p)). (xor)

    容易发现所有二元逻辑都会建立若干对边, 这称作2-SAT问题的对称性, 是算法正确的关键.

    较慢的算法 && 字典序最小解

    我们还可以枚举每个点, 然后假设其为 true (或者 false), 从该点dfs判断是否可行.

    这样可以求出一些特殊条件的解, 如最小字典序.

    时间复杂度 (O(nm)), 但是多数情况跑不满.

    代码

    //任意解
    int chos[nsz];
    int dfn[nsz*2],pd=0,low[nsz*2],inscc[nsz*2],ps=0;
    int stk[nsz*2],top=0,vi[nsz*2];
    void tarj(int p){
    	dfn[p]=low[p]=++pd;
    	stk[++top]=p,vi[p]=1;
    	for(auto v:edge[p]){
    		if(dfn[v]==0){
    			tarj(v);
    			low[p]=min(low[p],low[v]);
    		}
    		else if(vi[v])low[p]=min(low[p],dfn[v]);
    	}
    	if(low[p]==dfn[p]){//scc
    		++ps;
    		int v;
    		do{
    			v=stk[top];
    			inscc[v]=ps,vi[v]=0,--top;
    		}while(v!=p);
    	}
    }
    
    bool sat2(){//toefl ielts sat
    	rep(i,2,n*2+1)if(dfn[i]==0)tarj(i);
    	rep(i,1,n){
    		if(inscc[i<<1]==inscc[i<<1|1])return 0;//no solution
    		chos[i]=inscc[i<<1|1]<inscc[i<<1];
    	}
    	return 1;
    }
    
  • 相关阅读:
    【python入门到放弃】冒泡排序
    【python入门到放弃】变量、常量与注释
    环信和融云实现跨应用聊天
    swift里类方法和构造方法的使用来减少代码冗余提高开发效率
    git 常用命令 使用及iOS开发使用git管理项目步骤
    获取IPA包文件中的图片资源
    iOS11适配和iPhonex适配资料收集整理
    IOS 开发delegate和block的区别整理资料收集 (文章中内容有参考网络资料)
    IOS开发中集合操作 处理数据的 交集 并集 差集
    联系苹果人员的方式(转)
  • 原文地址:https://www.cnblogs.com/ubospica/p/10753404.html
Copyright © 2020-2023  润新知