Cod sursa(job #2681415)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 5 decembrie 2020 13:53:23
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 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<int> ord, val, compId;
	vector<bool> vis;
	vector<vector<int>> adj, adjt;

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

	void addEdge(int x, int y) {
		x = (x < 0 ? -2 * x - 2 : 2 * x - 1);
		y = (y < 0 ? -2 * y - 2 : 2 * y - 1);
		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 id) {
		vis[v] = false;
		compId[v] = id;
		if(val[v] == -1) val[v] = 0, val[v ^ 1] = 1;
		for(auto u : adjt[v]) if(vis[u]) dfst(u, id);
	}

	bool solve() {
		val.assign(n, -1);

		for(int i = 0; i < n; ++i) if(!vis[i]) dfs(i);
		for(int nr = 0, i = n - 1; i >= 0; --i) if(vis[ord[i]]) dfst(ord[i], nr++);

		for(int i = 0; i < n; i += 2) if(compId[i] == compId[i + 1]) return false;
		return true;
	}

	int 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;
}