zoukankan      html  css  js  c++  java
  • 题解 P4782 【【模板】2-SAT 问题】

    nn 个布尔变量 x1x_1 xnsim x_n ,另有 mm 个需要满足的条件,每个条件的形式都是 「xix_itrue / falsexjx_j 为 true / false」。比如 「x1x_1 为真或 x3x_3 为假」、「x7x_7 为假或 x2x_2 为假」。

    2-SAT 问题的目标是给每个变量赋值使得所有条件得到满足。

    前置知识:

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    template<typename T>inline void read(T &FF){
    	T RR=1;FF=0;char CH=getchar();
    	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
    	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
    	FF*=RR;
    }
    const int MAXN=3e6+10;
    int n,m,a,b,a1,b1,dfn[MAXN],low[MAXN],tot,s[MAXN],sp,sccnum[MAXN],scccnt;
    vector<int>E[MAXN];
    void tarjan(int u){
    	s[sp++]=u;
    	dfn[u]=low[u]=++tot;
    	for(auto v:E[u])
    		if(!dfn[v]){
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		}else if(!sccnum[v]){
    			low[u]=min(low[u],dfn[v]);
    		}
    	if(dfn[u]==low[u]){
    		scccnt++;
    		do{
    			sccnum[s[--sp]]=scccnt;
    		}while(s[sp]!=u);
    	}
    }
    int main(){
    	read(n);read(m);
    	for(int i=1;i<=m;i++){
    		read(a);read(a1);read(b);read(b1);
            E[a+(a1^1)*n].push_back(b+b1*n);
            E[b+(b1^1)*n].push_back(a+a1*n);
    	}
    	for(int i=1;i<=(n<<1);i++)
    		if(!dfn[i])tarjan(i);
    	for(int i=1;i<=(n<<1);i++)
    		if(sccnum[i]==sccnum[i+n])return puts("IMPOSSIBLE"),0;
    	puts("POSSIBLE");
    	for(int i=1;i<=n;i++)cout<<(sccnum[i]>sccnum[i+n])<<" ";
    	return 0;
    }
    /*
    3 1
    1 1 3 0
    */
    
  • 相关阅读:
    阻止所有普通账号登录服务器
    grep命令
    redis集群配置和节点管理
    redis的安装和配置
    shell特殊字符
    获取docker容器的ip地址
    mysql5.6.38误删除root用户后的一系列问题及解决办法
    CenrOS7.5安装msyql5.7.24
    使用163邮箱的smtp ssl端口发送邮件
    linux统计大文件行数的命令效率大对比
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816933.html
Copyright © 2011-2022 走看看