Cod sursa(job #390545)

Utilizator AndreyPAndrei Poenaru AndreyP Data 3 februarie 2010 22:36:05
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.57 kb
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<bitset>
#include<algorithm>
using namespace std;
#define M 200010
#define pb push_back
int n,n1;
int nc;
int con[M];
int ind[M],indlow[M];
int indice;
int deg[M];
bitset<M> inst,e,rez;
vector<int> a[M];
vector<int> b[M];
vector<int> c[M];
stack<int> st;
inline void citire()
{
	int m,x,y;
	scanf("%d%d",&n,&m);
	n1=n<<1;
	for(int i=0; i<m; ++i)
	{
        	scanf("%d%d",&x,&y);
		if(x<0)
			x=-x+n;
		if(y<0)
			y=-y+n;
                a[x<=n ? x+n : x-n].pb(y);
		a[y<=n ? y+n : y-n].pb(x);
	}
}
void sterge(vector<int> &x)
{
	vector<int> aux;
	aux.swap(x);
}
inline void adauga(int nod)
{
	for(size_t i=0,lim=a[nod].size(); i<lim; ++i)
	{
		if(e[con[a[nod][i]]]==1)
			continue;
		e[con[a[nod][i]]]=1;
		b[nc].pb(con[a[nod][i]]);
		++deg[con[a[nod][i]]];
	}
	sterge(a[nod]);
}
void tarjan(int nod)
{
	ind[nod]=indlow[nod]=++indice;
	inst[nod]=1;
	st.push(nod);

	for(size_t i=0,lim=a[nod].size(); i<lim; ++i)
	{
		if(ind[a[nod][i]]==0)
		{
			tarjan(a[nod][i]);
			if(indlow[nod]>indlow[a[nod][i]])
				indlow[nod]=indlow[a[nod][i]];
		}
		else
		if(inst[a[nod][i]]==1)
		{
			if(indlow[nod]>indlow[a[nod][i]])
				indlow[nod]=indlow[a[nod][i]];
		}
	}

	if(ind[nod]==indlow[nod])
	{
		int nod1;
		++nc;
		e.reset();
		e[nc]=1;
		e[0]=nc;
		do
		{
			nod1=st.top();
			inst[nod1]=0;
			st.pop();
			con[nod1]=nc;
                        c[nc].pb(nod1);
			adauga(nod1);
		}while(nod1!=nod);
	}
}
inline void tareConexe()
{ 
	for(int i=1; i<=n1; ++i)
	{
		if(ind[i]==0)
			tarjan(i);
	}
}
inline void verif()
{
	for(int i=1; i<=n; ++i)
	{
		if(con[i]==con[i+n])
		{
			fputs("-1\n",stdout);
			exit(0);
		}
	}
}
inline void rezolva()
{
	inst.reset();
	ind[0]=0;
	
	int nod;
	for(int i=1; i<=nc; ++i)
	{
		if(deg[i]==0)
			ind[++ind[0]]=i;
	}
	for(int i=1; i<=ind[0]; ++i)
	{
		nod=ind[i];
		for(size_t j=0,lim=b[nod].size(); j<lim; ++j)
		{
			--deg[b[nod][j]];
			if(deg[b[nod][j]]==0)
				ind[++ind[0]]=b[nod][j];
		}
	}

	int j=1;
	for(int i=1; (i<<1)<=nc; ++i)
	{ 

        	for(; j<=ind[0] && inst[ind[j]]==1; ++j)
			;
		nod=ind[j];
		inst[ind[j]]=1;

		for(size_t k=0,lim=c[nod].size(); k<lim; ++k)
		{
			if(c[nod][k]<=n)
				rez[c[nod][k]]=0;
			else
				rez[c[nod][k]-n]=1;
		}
                inst[con[(c[nod].front()<=n ? c[nod].front()+n : c[nod].front()-n)]]=1;
	}
}
inline void scrie()
{
	for(int i=1; i<n; ++i)
		printf("%d ",rez[i]==1 ? 1 : 0);
	printf("%d\n",rez[n]==1 ? 1 : 0);
}	
int main()
{
	freopen("2sat.in","r",stdin);
	freopen("2sat.out","w",stdout);

	citire();
	tareConexe();
	verif();
	rezolva();
	scrie();

	return 0;
}