Cod sursa(job #383881)

Utilizator raduzerRadu Zernoveanu raduzer Data 18 ianuarie 2010 16:43:32
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.32 kb
#include <cstdio>
#include <vector>
using namespace std;

#define pb push_back
#define forit(it, v) for(__typeof(v.begin()) it = v.begin(); it != v.end(); ++it)

const int MAX_N = 200010;

int n, m, z, sol;
int f[MAX_N], q[MAX_N], d[MAX_N];
vector <int> v[2][MAX_N], s[MAX_N];

int inv(int nod) { return (nod + n) % (2 * n); }

void df(int nod, int t)
{
	if (f[nod] == t + 1)
		return;
	f[nod] = t + 1;

	if (t)
		s[sol].pb(nod);

	forit(it, v[t][nod])
		df(*it, t);

	if (!t)
		q[++z] = nod;
}

int main()
{
	int i, r1, r2;
	freopen("2sat.in", "r", stdin);
	freopen("2sat.out", "w", stdout);

	scanf("%d %d", &n, &m);

	for (i = 1; i <= m; ++i)
	{
		scanf("%d %d", &r1, &r2);

		r1 = (r1 < 0) ? n + (-r1) : r1;
		r2 = (r2 < 0) ? n + (-r2) : r2;

		v[0][inv(r1)].pb(r2);
		v[0][inv(r2)].pb(r1);

		v[1][r2].pb(inv(r1));
		v[1][r1].pb(inv(r2));
	}

	for (i = 1; i <= 2 * n; ++i)
		if (!f[i])
			df(i, 0);

	for (i = 2 * n; i; --i)
		if (f[q[i]] != 2)
		{
			++sol;
			df(q[i], 1);
		}

	for (; sol; --sol)
		forit(it, s[sol])
			d[*it] = sol;

	for (i = 1; i <= n; ++i)
	{
		f[i] = f[i + n] = -1;

		if (d[i] == d[i + n])
		{
			printf("-1\n");
			return 0;
		}
	}

	for (i = 2 * n; i; --i)
		if (f[i] < 0)
		{
			forit(it, s[d[i]])
				f[*it] = 1;

			forit(it, s[d[inv(i)]])
				f[*it] = 0;
		}

	for (i = 1; i <= n; ++i)
		printf("%d ", f[i]);
}