Cod sursa(job #2681384)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 5 decembrie 2020 12:31:47
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.71 kb
#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define dbg(...) cerr << #__VA_ARGS__ << " ->", debug_out(__VA_ARGS__)
#define dbg_p(x) cerr<<#x": "<<(x).first<<' '<<(x).second<<endl
#define dbg_v(x, n) {cerr<<#x"[]: ";for(long long _=0;_<n;++_)cerr<<(x)[_]<<' ';cerr<<endl;}
#define all(v) v.begin(), v.end()
#define fi first
#define se second
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << " " << H; debug_out(T...);}

template<typename T1, typename T2>
ostream& operator <<(ostream &out, const pair<T1, T2> &item) {
	out << '(' << item.first << ", " << item.second << ')';
	return out;
}

template <typename T>
ostream& operator <<(ostream &out, const vector<T>& v) {
	for(const auto &item : v) out << item << ' ';
	return out;
}

struct Sat {
	int n;
	vector<bool> vis;
	vector<int> ord, comp, val;
	vector<vector<int>> adj, adjt, nodes;

	Sat(int n) : n(n), adj(2 * n), adjt(2 * n), nodes(2 * n) {}

	void addEdge(int x, int y) {
		x = (x > 0 ? 2 * x - 1 : -2 * x - 2);
		y = (y > 0 ? 2 * y - 1 : -2 * y - 2);
		adj[x].push_back(y);
		adjt[y].push_back(x);
	}

	void addClause(int x, int y) {
		addEdge(-x, y);
		addEdge(-y, x);
	}

	void dfs(int v) {
		vis[v] = true;
		for(auto u : adj[v]) if(!vis[u]) dfs(u);
		ord.push_back(v);
	}

	void dfst(int v, int nr) {
		vis[v] = false;
		comp[v] = nr;
		nodes[nr].push_back(v);
		for(auto u : adjt[v]) if(vis[u]) dfst(u, nr);
	}

	bool solve() {
		int nr = 0;
		vis.assign(2 * n, false);
		comp.assign(2 * n, -1);
		for(int i = 0; i < 2 * n; ++i) if(!vis[i]) dfs(i);
		for(int i = 2 * n - 1; i >= 0; --i) if(vis[ord[i]]) dfst(ord[i], nr++);
		for(int i = 0; i < 2 * n; ++i) if(comp[i] == comp[i ^ 1]) return false;

		vector<int> in(nr, 0);
		for(int i = 0; i < 2 * n; ++i) for(auto u : adj[i]) if(comp[i] != comp[u]) ++in[comp[u]];
		
		val.assign(2 * n, -1);
		
		queue<int> q;
		for(int i = 0; i < nr; ++i) if(!in[i]) q.push(i);
		for(; !q.empty(); q.pop()) {
			for(auto v : nodes[q.front()]) {
				if(val[v] == -1) val[v] = 0, val[v ^ 1] = 1;			
				for(auto u : adj[v]) if(comp[v] != comp[u] && (--in[comp[u]]) == 0) q.push(comp[u]);
			}
		}

		return true;
	}

	bool get(int i) {
		return val[2 * i - 1];
	}
};

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

	int n, m, x, y;

	cin >> n >> m;

	Sat sat(n);

	for(int i = 1; i <= m; ++i) {
		cin >> x >> y;
		sat.addClause(x, y);
	}

	if(!sat.solve()) cout << -1 << '\n';
	else {
		for(int i = 1; i <= n; ++i) cout << sat.get(i) << ' ';
		cout << '\n';
	}

	return 0;
}