zoukankan      html  css  js  c++  java
  • 算法笔记——2-SAT

    前置知识:

    其实这个东西跟并查集有点异曲同工。

    如果要满足 ax=0/1a_x=0/1ay=0/1a_y=0/1 的话。

    这个东西就跟食物链差不多了。

    我们先开 22 倍空间。

    fif_i 表示 ai=0a_i=0

    fi+nf_{i+n} 表示 ai=1a_i=1

    所以我们就开始连边。

    连完边以后,我们就可以开始跑强联通分量。

    我们发现在一个强联通内的变量值一定是相等的。

    #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;
    }
    

    例题:

  • 相关阅读:
    SQL Server 造成cpu 使用率高的 6 原因
    SQL Server SQLOS
    flask数据库操作
    redis数据类型
    python3中__get__,__getattr__,__getattribute__的区别
    强弱类型,动静态语言
    函数式编程和面向对象编程
    数据库事务的四个特性和含义
    流畅的python
    Python中__repr__和__str__区别
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816934.html
Copyright © 2011-2022 走看看