Cod sursa(job #1712898)

Utilizator retrogradLucian Bicsi retrograd Data 4 iunie 2016 01:26:30
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.25 kb
/*************************************************************\
~*********************ENJOY THE SILENCE***********************~
\*************************************************************/

#include <bits/stdc++.h>
using namespace std;

/*******************Debugging defines*************************/

#define ok_dump() cerr<<"OK\n"
#define var_dump(x) cerr<<#x": "<<x<<'\n'
#define arr_dump(x, n) {cerr<<#x"[]: ";\
	for(int _=1;_<=n;++_) cerr<<x[_]<<" ";cerr<<'\n';}

/*************************************************************/


struct TwoSAT {

	vector<vector<int>> G, G_T;
	vector<int> Viz;
	vector<bool> Sol, True;
	vector<int> Stack;
	bool no_sol;
	int n;

	TwoSAT(int n) : n(n), G(2 * n), G_T(2 * n), Viz(2 * n), 
		Sol(n, 0), True(2 * n, 0) {

		Stack.reserve(2 * n);
	}

	void AddEdge(int a, bool pa, int b, bool pb) {
		G[2 * a + pa].push_back(2 * b + pb);
		G_T[2 * b + pb].push_back(2 * a + pa);
	}

	void dfs_forward(int node) {
		Viz[node] = true;

		for(auto vec : G[node]) {
			if(!Viz[vec])
				dfs_forward(vec);
		}

		Stack.push_back(node);
	}

	void dfs_backward(int node) {
		if(True[node])
			no_sol = true;
		Viz[node] = true;
		True[node ^ 1] = true;

		Sol[node / 2] = (node & 1 ^ 1);

		for(auto vec : G_T[node]) {
			if(!Viz[vec])
				dfs_backward(vec);
		}
	}

	void Solve() {
		fill(Viz.begin(), Viz.end(), 0);
		for(int i = 0; i < 2 * n; ++i) {
			if(!Viz[i])
				dfs_forward(i);
		}

		no_sol = false;
		fill(Viz.begin(), Viz.end(), 0);
		for(int i = 2 * n - 1; i >= 0; --i) {
			if(!Viz[Stack[i]] && !Viz[Stack[i] ^ 1])
				dfs_backward(Stack[i]);
		}
	}
};

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

	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n, m;
	cin >> n >> m;

	TwoSAT sat(n);

	while(m--) {
		int a, b;
		cin >> a >> b;
		bool ta = (a > 0);
		bool tb = (b > 0);
		a = abs(a) - 1;
		b = abs(b) - 1;

		sat.AddEdge(a, ta ^ 1, b, tb);
		sat.AddEdge(b, tb ^ 1, a, ta);
	}

	sat.Solve();

	if(sat.no_sol) {
		cout << "-1\n";
	} else {
		for(int i = 0; i < n; ++i)
			cout << sat.Sol[i] << " ";
	}
	
	return 0;
}

/*************************************************************\
~*********************ENJOY THE SILENCE***********************~
\*************************************************************/