Cod sursa(job #468793)

Utilizator ilincaSorescu Ilinca ilinca Data 5 iulie 2010 01:17:47
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>

#define nmax 100005
#define pb push_back

using namespace std;

typedef pair <int, int> ii;
typedef vector <int> VI;

int n, m, nc, val [2*nmax], grup [2*nmax], deg [2*nmax];
VI c, g [2*nmax], gt [2*nmax], gc [2*nmax], ctc [2*nmax];
bool viz [2*nmax];

inline int neg (int x)
{return (x <= n)? x+n:x-n;}


void scan ()
{
	int a, b;
	scanf ("%d%d", &n, &m);
	for (int i=1; i <= m; ++i)
	{
		scanf ("%d%d", &a, &b);
		if (a < 0) a=(-1)*a+n;
		if (b < 0) b=(-1)*b+n;
		g [neg(a)].pb (b);
		g [neg(b)].pb (a);
		gt [b].pb (neg (a));
		gt [a].pb (neg (b));
	}
}

void dfs1 (int x)
{
	viz [x]=true;
	for (int i=0; i < g [x].size (); ++i)
		if (!viz [g [x] [i]]) dfs1 (g [x] [i]);
	c.pb (x);
}

void dfs2 (int x)
{
	grup [x]=nc;
	ctc [nc].pb (x);
	for (int i=0; i < gt [x].size (); ++i)
		if (!grup [gt [x] [i]]) {dfs2 (gt [x] [i]);}

}

void scc ()
{
	int i;
	for (i=1; i <= 2*n; ++i)
		if (!viz [i]) dfs1 (i);
	for (i=c.size ()-1; i >= 0; --i)
		if (!grup [c [i]]) {++nc;dfs2 (c [i]);}
	for (i=1; i <= n; ++i) 
		if (grup [i] == grup [neg (i)]) 
		{
			printf ("-1\n"); exit (0);
		}
}

void rez ()
{
	int i, j, k, x, gr;
	queue <int> q;
	for (i=1; i <= nc; ++i)
		for (j=0; j < ctc [i].size (); ++j)
			for (k=0; k < g [ctc [i] [j]].size (); ++k)
				if (grup [g [ctc [i] [j]] [k]] != i) ++deg [grup [g [ctc [i] [j]] [k]]];
	for (i=1; i <= nc; ++i) if (deg [i] == 0) q.push (i);
	while (!q.empty ())
	{
		x=q.front ();
		q.pop ();
		if (val [x] != 1) val [grup [neg (ctc [x] [0])]]=1;
		else continue;
		val [x]=0;
		for (i=0; i < ctc [x].size (); ++i)
			for (j=0; j < g [ctc [x] [i]].size (); ++j)
				if (grup [g [ctc [x] [i]] [j]] != x)
				{
					gr=grup [g [ctc [x] [i]] [j]];
					--deg [gr];
					if (deg [gr] == 0) q.push (gr);
				}
	}
}

void print ()
{
	for (int i=1; i <= n; ++i)
		printf ("%d ", val [grup [i]]);
	printf ("\n");
}

int main ()
{
	freopen ("2sat.in", "r", stdin);
	freopen ("2sat.out", "w", stdout);
	scan ();
	scc ();
//	for (int i=1; i <= 2*n; ++i) fprintf (stderr, "%d %d\n", i, grup [i]);
	rez ();
	print ();
	return 0;
}