zoukankan      html  css  js  c++  java
  • 2-SAT问题学习笔记+例题[洛谷P4792]

    一个不错的2-SAT文章:传送门

    问题初入

    什么是2-SAT

    SAT是适定性(Satisfiability)问题的简称 。一般形式为k-适定性问题,简称 k-SAT。

    首先,把「2」和「SAT」拆开。SAT 是 Satisfiability 的缩写,意为可满足性。即一串布尔变量,每个变量只能为真或假。要求对这些变量进行赋值,满足布尔方程。

    如何实现2-SAT

    一道例题:洛谷P4782 2-SAT例题

    首先将每个or的问题转换成假->真问题

    然后跑缩点

    因为缩点中跑出来的强连通分量的拓扑序已经在过程中求出(虽然是逆序),然后再判断一遍

    当 x 所在的强连通分量的拓扑序在 ¬x 所在的强连通分量的拓扑序之后取 x 为真 就可以了。在使用 Tarjan 算法缩点找强连通分量的过程中,已经为每组强连通分量标记好顺序了不过是反着的拓扑序

    上代码

    #include<bits/stdc++.h>
    #define re register
    #define ll long long
    using namespace std;
    inline int read()
    {
    	ll k=1,sum=0;
    	char c=getchar();
    	for(;c<'0' || c>'9';c=getchar()) if(c=='-') k=-1;
    	for(;c>='0' && c<='9';c=getchar()) sum=sum*10+c-'0';
    	return sum*k;
    }
    const int N=1e6+10;
    int n,m;
    struct Edge{
    	int to,nxt;
    };
    int head[N<<1],cnt;
    Edge edge[N<<2];
    inline void Add(int x,int y){
    	edge[++cnt].to=y;edge[cnt].nxt=head[x];head[x]=cnt;
    }
    int dfn[N<<1],ins[N<<1],color[N<<1],low[N<<1],col;
    bool vis[N<<1];
    int id;
    stack<int> S;
    inline void Tarjan(int x){
    	S.push(x);
    	ins[x]=1;
    	dfn[x]=low[x]=++id;
    	for(re int i=head[x];i;i=edge[i].nxt){
    		int y=edge[i].to;
    		if(!dfn[y]){
    			Tarjan(y);
    			low[x]=min(low[x],low[y]);
    		}
    		else if(ins[y]) low[x]=min(low[x],low[y]);
    	}
    	if(low[x]==dfn[x]) {
    		re int k=-1;++col;
    		while(k!=x){
    			k=S.top();S.pop();
    			ins[k]=0;
    			color[k]=col;
    		}
    	}
    }
    int main()
    {
    	n=read();m=read();
    	for(re int k=1;k<=m;++k){
    		int i=read(),a=read(),j=read(),b=read();
    		Add(i+n*(a&1),j+n*(b^1));
    		Add(j+n*(b&1),i+n*(a^1));
    	}
    	for(re int i=1;i<=n<<1;++i){
    		if(!dfn[i]) Tarjan(i);
    	}
    	for(re int i=1;i<=n;++i)
    	if(color[i]==color[i+n]){
    		puts("IMPOSSIBLE");
    		return 0;
    	}
    	puts("POSSIBLE");
    	for(re int i=1;i<=n;++i) {
    		cout<<((color[i]<color[i+n])?1:0)<<" ";
    	}
    	return 0;
    }
    
  • 相关阅读:
    如何使用gitbash 把你的代码托管到github
    发送邮件错误常见错误码
    使用snipworks/php-smtp发送邮件
    微信支付demo
    Linux——ps命令
    数组对象互转
    变量名下划线和驼峰互转
    对象数组转换
    curl请求
    百度地图接口的使用
  • 原文地址:https://www.cnblogs.com/IcedMoon/p/11432288.html
Copyright © 2011-2022 走看看