P4782 【模板】2-SAT 问题

P4782 【模板】2-SAT 问题

solve

模板题,注意建边的方向决定了最后的判断

code

#include<cstdio>
#include<vector>
#include<stack>
const int maxn=1e6+5;
int n,m,vis[maxn<<1],low[maxn<<1],dfn[maxn<<1],tot,scc_cnt,color[maxn<<1];
std::vector<int> g[maxn<<1];
std::stack<int> stk;
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
void tarjan(int u){
	low[u]=dfn[u]=++tot;
	stk.push(u);vis[u]=1;
	for(int i=0;i<g[u].size();i++){
		int v=g[u][i];
		if(!dfn[v]){tarjan(v);low[u]=std::min(low[u],low[v]);}
		else if(vis[v])low[u]=std::min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		++scc_cnt;
		do{
			color[u]=scc_cnt;
			u=stk.top();stk.pop();vis[u]=0;
		}while(low[u]!=dfn[u]);
	}
}
int main(){
	n = read(), m = read();
	for (int i = 0; i < m; ++i) {
		int a = read(), va = read(), b = read(), vb = read();
		g[a + n * (va ^ 1)].push_back(b + n * (vb & 1));
		g[b + n * (vb ^ 1)].push_back(a + n * (va & 1));
	}
	for(int i=1;i<=(n<<1);i++) (!dfn[i])&&(tarjan(i),0);
	for(int i=1;i<=n;i++)
		if(color[i]==color[i+n]){
			puts("IMPOSSIBLE");
			return 0;
		}
	puts("POSSIBLE");
	for(int i=1;i<=n;i++)
		printf("%d",color[i]>color[i+n]),putchar(' ');
	return 0;
}
原文地址:https://www.cnblogs.com/martian148/p/15191555.html