Cod sursa(job #383646)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 17 ianuarie 2010 15:18:25
Problema 2SAT Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include<stdio.h>
#include<vector>
#define non(x) x<=n?x+n:x-n
#define nod(x) x>0?x:n-x
#define NN 200010
using namespace std;
vector<int> v[NN],S,T[NN];
int n,m,i,x,y,X,Y,N,NC,c,V[NN],C[NN],D[NN],L[NN],ok,G[NN];
void read(),solve(),visit(int p);
int main()
{
	read();
	solve();
	return 0;
}
void read()
{
	freopen("2sat.in","r",stdin);
	freopen("2sat.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		x=nod(x);X=non(x);G[x]++;
		y=nod(y);Y=non(y);G[y]++;
		v[X].push_back(y);
		v[Y].push_back(x);
	}
}
void solve()
{
	vector<int>::iterator it,jt;
	ok=1;
	for(i=1;i<=2*n;i++)
		if(!V[i])
		{
			N=0;
			visit(i);			
		}
	for(i=1;i<=n;i++)if(C[i]==C[non(i)]){printf("-1\n");return;}
	for(i=1;i<=2*n;i++)D[i]=C[non(i)];
	for(i=1;i<=2*n;i++)
		for(it=v[i].begin();it!=v[i].end();it++)
			if(C[i]==C[*it])G[*it]--;
	for(i=1;i<=2*n;i++){ if(G[i]==0)S.push_back(i);V[i]=0;}
	for(it=S.begin();it!=S.end();it++)
	{
		for(jt=v[*it].begin();jt!=v[*it].end();jt++)
			if(C[*it]!=C[*jt])
			{
				G[*jt]--;
				if(!G[*jt])S.push_back(*jt);
			}
		if(V[*it])continue;
		c=C[*it];
		for(jt=T[c].begin();jt!=T[c].end();jt++)
			V[*jt]=1;
		c=D[*it];
		for(jt=T[c].begin();jt!=T[c].end();jt++)
			V[*jt]=2;
	}
	for(i=1;i<=n;i++)printf("%d ",V[i]-1);
}
void visit(int p)
{   
	vector<int>::iterator it;
	V[p]=1;
	S.push_back(p);
	N++;
	D[p]=N;
	L[p]=N;
    for(it=v[p].begin();it!=v[p].end();it++)
    {
		if(!V[*it])
			visit(*it);
		if(!ok)return;
	    L[p]=(L[p]<L[*it])?L[p]:L[*it];
    }
    if(L[p]==D[p])
    {
		NC++;
		for(;;)
		{
			if(S.empty())break;
			if(L[S.back()]-L[p])break;
			T[NC].push_back(S.back());
			C[S.back()]=NC;
			S.pop_back();
		}
	}
}