Cod sursa(job #799841)

Utilizator ChallengeMurtaza Alexandru Challenge Data 20 octombrie 2012 10:45:56
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.24 kb
#include <fstream>
#include <vector>

using namespace std;

const char InFile[]="2sat.in";
const char OutFile[]="2sat.out";
const int MaxN=100111;
const int MaxM=200111;
const int MaxN2=(MaxN<<1);

ifstream fin(InFile);
ofstream fout(OutFile);

int N,M,x,y,Comp[MaxN2],S[MaxN2],ind,comp,low[MaxN2],niv[MaxN2],SOL[MaxN2];
vector<int> G[MaxN2],GC[MaxN2],El[MaxN2];
bool gotSol=true;

void Tarjan(int nod)
{
	S[++S[0]]=nod;
	niv[nod]=low[nod]=++ind;
	for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
	{
		int &vcn=*it;
		if(!low[vcn])
		{
			Tarjan(vcn);
		}
		else if(low[vcn]>0)
		{
			if(low[nod]>low[vcn])
			{
				low[nod]=low[vcn];
			}
		}
	}
	
	if(niv[nod]==low[nod])
	{
		++comp;
		int tnod;
		do
		{
			tnod=S[S[0]];
			--S[0];
			low[tnod]=-low[tnod];
			Comp[tnod]=comp;
			El[comp].push_back(tnod);
		}while(tnod!=nod);
	}
}

void DFS(int nod)
{
	low[nod]=0;
	for(vector<int>::iterator it=GC[nod].begin();it!=GC[nod].end();++it)
	{
		if(low[nod])
		{
			DFS(*it);
		}
	}
	
	S[++S[0]]=nod;
}

inline int inv(int x)
{
	if(x<=N)
	{
		return x+N;
	}
	return x-N;
}

int main()
{
	fin>>N>>M;
	for(register int i=1;i<=M;++i)
	{
		fin>>x>>y;
		if(x<0)
		{
			x=-x+N;
		}
		if(y<0)
		{
			y=-y+N;
		}
		G[inv(x)].push_back(y);
		G[inv(y)].push_back(x);
	}
	fin.close();
	
	for(register int i=1;i<=N*2;++i)
	{
		if(!low[i])
		{
			Tarjan(i);
		}
	}
	
	for(register int i=1;i<=N;++i)
	{
		if(Comp[i]==Comp[i+N])
		{
			gotSol=false;
			goto afis;
		}
	}
	
	for(register int i=1;i<=(N<<1);++i)
	{
		for(vector<int>::iterator it=G[i].begin();it!=G[i].end();++it)
		{
			int &vcn=*it;
			GC[Comp[i]].push_back(Comp[vcn]);
		}
	}
	
	for(register int i=1;i<=(N<<1);++i)
	{
		if(low[i])
		{
			DFS(i);
		}
	}
	
	while(S[0])
	{
		int c=S[S[0]];
		for(vector<int>::iterator it=El[c].begin();it!=El[c].end();++it)
		{
			int &nod=*it;
			if(SOL[nod]==0)
			{
				SOL[nod]=-1;
				SOL[inv(nod)]=1;
			}
		}
		--S[0];
	}
	
afis:
	if(!gotSol)
	{
		fout<<"-1";
	}
	else
	{
		for(register int i=1;i<=N;++i)
		{
			if(SOL[i]==-1)
			{
				fout<<"0 ";
			}
			else
			{
				fout<<"1 ";
			}
		}
	}
	fout.close();
	return 0;
}