Cod sursa(job #480083)

Utilizator razvi9Jurca Razvan razvi9 Data 26 august 2010 13:21:36
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <fstream>
#include <vector>
using namespace std;
typedef unsigned int uint;

int n, m;
vector<vector<int> > a, ta;
vector<vector<int> > comp;
vector<vector<int> > b;
vector<char> result, viz;
vector<int> w;
vector<int> sorted;

int node(int x)
{
	if (x < 0)
		return n - x;
	return x;
}

void DF1(int v)
{
	viz[v] = 1;

	for(uint i=0;i<a[v].size();++i)
		if(!viz[a[v][i]])
			DF1(a[v][i]);

	sorted.push_back(v);
}

void DF2(int v, int c)
{
	viz[v] = 1;
	w[v] = c;
	comp[c].push_back(v);

	for(uint i=0;i<ta[v].size();++i)
		if(!viz[ta[v][i]])
			DF2(ta[v][i], c);
}

void tareConex()
{
	int sz = 2 * n;
	for(int i=1;i<=sz;++i)
		if(!viz[i])
			DF1(i);

	memset(&viz[0], 0, viz.size() * sizeof(int));

	for(int i=sorted.size() - 1;i>=0;--i)
		if(!viz[sorted[i]])
		{
			comp.push_back(vector<int>());
			DF2(sorted[i], comp.size() - 1);
		}
	b.resize(comp.size());

	for(uint i=1;i<a.size();++i)
		for(uint j=0;j<a[i].size();++j)
			if (w[i] != w[a[i][j]])
				b[w[i]].push_back(w[a[i][j]]);	
}

void DF3(int v)
{
	viz[v] = 1;

	for(uint i=0;i<b[v].size();++i)
		if(!viz[b[v][i]])
			DF3(b[v][i]);

	sorted.push_back(v);
}

inline bool solve(int c, bool val)
{
	for(vector<int>::iterator it = comp[c].begin(); it != comp[c].end(); ++ it)
		if(result[*it] == -1 || result[*it] == val)
			result[*it] = val;
		else
			return false;
	return true;
}

bool solve()
{	
	sorted.clear();
	memset(&viz[0], 0, viz.size() * sizeof(int));
	memset(&result[0], -1, result.size());
	for(uint i=0;i<comp.size();++i)
		if(!viz[i])
		{
			DF3(i);
			int st = 0, dr = sorted.size() - 1;
			while(st <= dr)
			{
				if(!solve(sorted[st ++], true))
					return false;
				if(!solve(sorted[dr --], false))
					return false;
			}
		}
	return true;
}

int main()
{
	ifstream cin("2sat.in");
	ofstream cout("2sat.out");

	int x, y;
	cin >> n >> m;
	a.resize(2 * n + 1);
	ta.resize(2 * n + 1);
	result.resize(2 * n + 1);
	viz.resize(2 * n +  1);
	w.resize(2 * n + 1);
	while (m --)
	{
		cin >> x >> y;
		a[node(-x)].push_back(node(y));
		a[node(-y)].push_back(node(x));
		ta[node(x)].push_back(node(-y));
		ta[node(y)].push_back(node(-x));
	}

	tareConex();

	if(solve())
	{
		for(int i=1;i<=n;++i)
			cout << (result[i] ? '1' : '0') << ' ';
	}
	else
		cout << -1;

	return 0;
}