Cod sursa(job #428072)

Utilizator katakunaCazacu Alexandru katakuna Data 28 martie 2010 19:52:24
Problema 2SAT Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

#define Nmax 200010

int n, m, N, nr_comp;
int viz[Nmax], C[Nmax], sol[Nmax], IN[Nmax];
vector <int> G[Nmax], T[Nmax], S, ctc[Nmax], V[Nmax];
queue <int> Q;

int non (int x) {
	
	if (x <= n) return x + n;
	return x - n;
}

void citire () {

	int i, x, y;
	
	scanf ("%d %d", &n, &m);
	for (i = 1; i <= m; i++) {
		scanf ("%d %d", &x, &y);
		if (x < 0) x = -x + n;
		if (y < 0) y = -y + n;
		
		G[non(y)].push_back (x);
		T[x].push_back (non(y));
		
		G[non(x)].push_back (y);
		T[y].push_back (non(x));
	}
}

void DFSp (int nod) {
	
	viz[nod] = 1;
	for (vector <int>::iterator it = G[nod].begin (); it != G[nod].end (); it++)
		if (!viz[*it])
			DFSp (*it);
	
	S.push_back (nod);
}

void DFSm (int nod) {
	
	viz[nod] = 1; C[nod] = nr_comp; ctc[nr_comp].push_back (nod);
	for (vector <int>::iterator it = T[nod].begin (); it != T[nod].end (); it++)
		if (!viz[*it])
			DFSm (*it);
}

void ctc_graph () {
	
	for (int i = 1; i <= N; i++)
		for (int j = 0; j < (int)G[i].size (); i++)
			if ( C[i] != C[ G[i][j] ] ) {
				V[ C[i] ].push_back (C[ G[i][j] ]);
				IN [C[ G[i][j] ]]++;
			}
}

int main () {

	freopen ("2sat.in", "r", stdin);
	freopen ("2sat.out", "w", stdout);

	citire ();
	
	int i; N = 2 * n;
	for (i = 1; i <= N; i++)
		if (!viz[i])
			DFSp (i);
	
	memset (viz, 0, sizeof (viz));
	for (i = S.size () - 1; i >= 0; i--)
		if (!viz[S[i]]) {
			nr_comp++;
			DFSm (S[i]);
		}
	
	for (i = 1; i <= n; i++)
		if (C[i] == C[i + n]) {
			printf ("-1");
			return 0;
		}
	
	ctc_graph ();
	
	for (i = 1; i <= nr_comp; i++)
		if (!IN[i]) Q.push (i);
	
	int nod, fiu;
	for (; !Q.empty (); Q.pop ()) {
		nod = Q.front ();
		
		for (i = 0; i < (int) V[nod].size (); i++) {
			fiu = V[nod][i];
			IN[fiu]--;
			if (!IN[fiu]) Q.push (fiu);
		}
		
		for (i = 0; i < (int) ctc[nod].size (); i++) {
			fiu = ctc[nod][i];
			if (!sol[fiu]) {
				sol[fiu] = 1;
				sol[non(fiu)] = 2;
			}
		}
	}
	
	for (i = 1; i <= n; i++)
		printf ("%d ", sol[i] - 1);
	
	return 0;
}