P4782 【模板】2-SAT 问题

题意

分析

2-SAT模板题。

大概的意思是每个变量拆成两个点,分别表示选0和选1。

然后把“确定的二元关系”来连边,也就是如果存在\(a\)就必然存在\(b\)的话,就从\(a\)\(b\)连边。

接下来使用 \(tarjan\) 求出强连通分量。

判断就是:如果无解,那么至少存在一个变量,其两个点在同一个连通分量当中(也就是可以从“a”推出“非a”)。

否则解就是选择这个变量两个点中所属连通分量编号较小的那一个。(据说是拓扑序较小)

代码

#include<bits/stdc++.h>
using namespace std;
//#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
//char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline void read(T &x){
	x=0;char ch=getchar();bool f=false;
	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x=f?-x:x;
	return ;
}
template <typename T>
inline void write(T x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10^48);
	return ;
}
#define ll long long
const int N=2e6+5;
const ll INF=1e12,MOD=1e9+7;
const double eps=1e-6;
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int n,m,val[N];
ll Ans;
int head[N],to[N<<1],nex[N<<1],idx;
inline void add(int u,int v){nex[++idx]=head[u],to[idx]=v,head[u]=idx;return ;}
bool inst[N];
int sta[N],dfn[N],low[N],top,DFN,bl[N],SCC;
void tarjan(int x){
	dfn[x]=low[x]=++DFN;sta[++top]=x;inst[x]=true;
	for(int i=head[x];i;i=nex[i]){
		int y=to[i];
		if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
		else if(inst[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x]){
		SCC++;
		while(1){
			int d=sta[top--];
			bl[d]=SCC;
			inst[d]=false;
			if(d==x) break;
		}
	}
	return ;
}
signed main(){
	read(n),read(m);
	for(int i=1;i<=m;i++){
		int a,b,x,y;
		read(a),read(x),read(b),read(y);
		if(x&&y) add(a,b+n),add(b,a+n);
		else if(x&&!y) add(a,b),add(b+n,a+n);
		else if(!x&&y) add(a+n,b+n),add(b,a);
		else add(a+n,b),add(b+n,a);
	}
	for(int i=1;i<=(n<<1);i++) if(!dfn[i]) tarjan(i);
	bool fl=false;
	for(int i=1;i<=n;i++){
		if(bl[i]==bl[i+n]) fl=true;
		else{
			if(bl[i]<=bl[i+n]) val[i]=0;
			else val[i]=1;
		}
	}
	if(fl) puts("IMPOSSIBLE");
	else{
		puts("POSSIBLE");
		for(int i=1;i<=n;i++) write(val[i]),putchar(' ');
	}
	return 0;
}
posted @ 2021-07-20 21:06  __Anchor  阅读(34)  评论(0编辑  收藏  举报