Cod sursa(job #1570759)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 16 ianuarie 2016 20:09:52
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.86 kb
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

#define NMAX 200005

int N, M;

vector <int> G[NMAX], GT[NMAX];

int value[NMAX];
int nr_scc[NMAX];
int used[NMAX];
int scc_deg[NMAX];

vector<int> S;

vector <vector<int> > sccs;

inline int idx(int x) 
{
	return (x < 0) ? abs(x) + N : x;
}

inline int non( int x) 
{
	return (x > N) ? x - N : x + N;
}

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

void DFT(int n, vector<int> &scc)
{
	used[n] = 1;
	scc.push_back(n);
	for (vector <int>::iterator it = GT[n].begin(); it != GT[n].end(); ++it)
		if (!used[*it])
			DFT(*it, scc);
}

void make_sccs() 
{
	vector <int> scc;

	memset(used, 0, sizeof(used));
	for (int i = 1; i <= (N << 1); ++i)
		if (!used[i])
			DF(i);

	memset(used, 0, sizeof(used));	
	for (vector <int>::reverse_iterator it = S.rbegin(); it != S.rend(); ++it) 
	{
		if (!used[*it]) 
		{
			scc.clear();
			DFT(*it, scc);
			for (vector <int>::iterator it2 = scc.begin(); it2 != scc.end(); ++it2)
				nr_scc[*it2] = sccs.size();
			sccs.push_back(scc);
		}
	}
}

int main() 
{
	freopen("2sat.in", "rt", stdin);
	freopen("2sat.out", "w", stdout);

	cin >> N >> M;

	for (int i = 0; i < M; ++i) {
		int x, y;
		cin >> x >> y;

		G[non(idx(x))].push_back(idx(y));
		GT[idx(y)].push_back(non(idx(x)));
		G[non(idx(y))].push_back(idx(x));
		GT[idx(x)].push_back(non(idx(y)));
	}
	make_sccs();

	int impossible = false;
	for (int x = 1; x <= N; ++x)
	{
		if (nr_scc[x] == nr_scc[x + N])
		{
			impossible = true;
			break;
		}
	}

	if (!impossible) 
	{
		for (int x = 1; x <= (N << 1); ++x) 
		{
			for (vector <int>::iterator it = G[x].begin(); it != G[x].end(); ++it)
				if (nr_scc[x] != nr_scc[*it])
					scc_deg[nr_scc[*it]] ++;
		}
		queue <int> Q;
		for (int i = 1; i <= N; ++i) value[i] = -1;

		for (int id_scc = 0; id_scc < sccs.size(); ++id_scc)
		{
			if (scc_deg[id_scc] == 0)
				Q.push(id_scc);
		}
		while (!Q.empty()) 
		{
			int id_scc = Q.front();
			Q.pop();
			for (vector <int>::iterator it = sccs[id_scc].begin(); it != sccs[id_scc].end(); ++it) 
			{
				int x = (*it > N) ? *it - N : *it;
				if (value[x] == -1)
					value[x] = (*it > N) ? 1 : 0;
			}
			for (vector<int> :: iterator it = sccs[id_scc].begin(); it != sccs[id_scc].end(); ++it) 
			{
				for (vector<int> :: iterator it2 = G[*it].begin(); it2 != G[*it].end(); ++it2)
					if (nr_scc[*it] != nr_scc[*it2]) 
					{
						if ((--scc_deg[nr_scc[*it2]]) == 0)
							Q.push(nr_scc[*it2]);
					}
			}
		}
		for (int i = 1; i <= N; ++i)
			cout << value[i] << " ";
		cout << '\n';
	}
	else
		cout << -1 << '\n';

	return 0;
}