Cod sursa(job #383802)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 18 ianuarie 2010 10:10:29
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include<stdio.h>
#define non(x) x<=n?x+n:x-n
#define nod(x) x>0?x:n-x
#define NN 200010
struct nod{int vec;nod *urm;};
nod *Out[NN],*In[NN],*CT[NN],*S,*E;
int n,m,NC,LOW[NN],DFN[NN],VIZ[NN],CC[NN],num,*GRDC,*VALC,*VAL;
void read(),solve(),visit(int p);
int main()
{
	read();
	solve();
	return 0;
}
void read()
{
	int i,x,y,X,Y;
	nod *p;
	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);
		if(x+y==0)continue;
		x=nod(x);X=non(x);
		y=nod(y);Y=non(y);
		p=new nod;p->vec=x;p->urm=Out[Y];Out[Y]=p;
		p=new nod;p->vec=y;p->urm=Out[X];Out[X]=p;
		//p=new nod;p->vec=X;p->urm=In[y];In[y]=p;
		//p=new nod;p->vec=Y;p->urm=In[x];In[x]=p;
		
	}
}
void solve()
{
	int i,cf,ct;nod *p,*q,*r;
	for(i=1;i<=2*n;i++)if(!VIZ[i]){num=0;visit(i);}
	for(i=1;i<=n;i++)if(CC[i]==CC[i+n]){printf("-1\n");return;}
	VALC=LOW;GRDC=VIZ;
	for(i=1;i<=NC;i++){VALC[i]=-1;GRDC[i]=0;}
	for(i=1;i<=2*n;i++)
		for(p=Out[i];p;p=p->urm)
			if(CC[i]!=CC[p->vec])
				GRDC[CC[p->vec]]++;
	for(i=1;i<=NC;i++)
		if(!GRDC[i])
		{
			p=new nod;p->vec=i;p->urm=0;
			if(!S){S=E=p;}
			else {E->urm=p;E=p;}
		}
	while(S)
	{
		i=S->vec;cf=i;ct=CC[non(CT[i]->vec)];
		VALC[cf]=0;VALC[ct]=1;
		for(p=CT[cf];p;p=p->urm)
			for(q=Out[p->vec];q;q=q->urm)
				if(CC[q->vec]!=cf)
				{
					GRDC[CC[q->vec]]--;
					if(!GRDC[CC[q->vec]]&&VALC[CC[q->vec]]==-1)
					{
						r=new nod;r->vec=CC[q->vec];r->urm=0;E->urm=r;E=r;
					}
				}
		p=S;S=S->urm;delete p;
	}
	VAL=DFN;
	for(i=1;i<=NC;i++)
		for(p=CT[i];p;p=p->urm)
			VAL[p->vec]=VALC[i];
	for(i=1;i<=n;i++)printf("%d ",VAL[i]);
	printf("\n");
}
void visit(int I)
{
	int J;
	nod *p;
	VIZ[I]=1;num++;DFN[I]=LOW[I]=num;
	p=new nod;p->vec=I;p->urm=S;S=p;
	for(p=Out[I];p;p=p->urm)
	{
		if(VIZ[p->vec]==2)continue;
		if(!VIZ[p->vec])visit(p->vec);
		LOW[I]=LOW[I]<LOW[p->vec]?LOW[I]:LOW[p->vec];
	}
	if(DFN[I]==LOW[I])
	{
		NC++;
		for(;;)
		{
			J=S->vec;
			p=S;S=S->urm;delete p;
			p=new nod;p->vec=J;p->urm=CT[NC];CT[NC]=p;
			CC[J]=NC;VIZ[J]=2;
			if(J==I)break;
		}
	}
}