2-sat(模板)

题目
再次吐糟2-sat诡奇的建图

#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=2000005;
using namespace std;
template<typename T>inline void rd(T&x)
{
	char c;bool f=0;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
	x=c^48;
	while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
	if(f)x=-x;
}

int n,m,tot,col,k,belong[maxn],hd[maxn],dfn[maxn],low[maxn];

struct node{
 int fr,to,nt;
}e[maxn<<1];

stack<int>s;

inline void tarjan(int u)
{
	s.push(u);
	dfn[u]=low[u]=++tot;
	for(int i=hd[u];i;i=e[i].nt)
	{
		int v=e[i].to;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!belong[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u])
	{
		int v=-1;++col;
		while(u!=v)
		{
			v=s.top();
			s.pop();
			belong[v]=col;
		}
	}
}

inline void add(int x,int y)
{
	e[++k].fr=x;e[k].to=y;e[k].nt=hd[x];hd[x]=k;
}
int main()
{
	int a,b,c,d;
	rd(n),rd(m);
	inc(i,1,m)
	{
		rd(c),rd(a),rd(d),rd(b);
		add((!a)*n+c,b*n+d);
		add((!b)*n+d,a*n+c);
	}
	
	inc(i,1,n<<1)
	if(!dfn[i])tarjan(i);
	
	inc(i,1,n)
	if(belong[i]==belong[i+n])
	{
		printf("IMPOSSIBLE");
		re 0;
	}
	
	printf("POSSIBLE\n");
	inc(i,1,n)
	printf("%d ",belong[i]>belong[i+n]);
	re 0;
}
posted @ 2019-08-01 16:53  凉如水  阅读(295)  评论(0编辑  收藏  举报