Pagini recente » Cod sursa (job #1345464) | Cod sursa (job #720344) | Cod sursa (job #2965613) | Cod sursa (job #446729) | Cod sursa (job #2011423)
#include <bits/stdc++.h>
using namespace std;
/**
* 2SAT Solver
*
* Usage:
*
* Add edges with AddEdge(u, v)
* where u < 0 if not |u| and u > 0 if |u|
* (edges are of type u -> v), and call Solve().
*
* Compute the answer by doing Solve()
* - if there is no answer, return value will be empty
*
* Also, keep in mind the 1-indexing of literals!
**/
class TwoSAT {
struct Node {
vector<int> leg, gel;
bool vis, is_true;
};
vector<Node> T;
vector<bool> sol;
vector<int> stk;
bool no_sol;
int n;
void dfs_forward(int node) {
T[node].vis = true;
for (auto vec : T[node].leg)
if (!T[vec].vis)
dfs_forward(vec);
stk.push_back(node);
}
void dfs_backward(int node) {
T[node].vis = false;
// Set node's truth value to false
if (T[node].is_true) no_sol = true;
T[node ^ 1].is_true = true;
sol[node / 2] = ((node & 1) ^ 1);
// Whatever implies false is false
for (auto vec : T[node].gel)
if (T[vec].vis)
dfs_backward(vec);
}
int get_node(int x) {
if (x > 0) return 2 * (x - 1) + 1;
return 2 * (-x - 1);
}
public:
TwoSAT(int n) : T(2 * n), sol(n, 0), n(n) {
stk.reserve(2 * n);
}
void AddEdge(int a, int b) {
a = get_node(a); b = get_node(b);
T[a].leg.push_back(b);
T[b].gel.push_back(a);
}
vector<bool> Solve() {
for(int i = 0; i < 2 * n; ++i)
dfs_forward(i);
no_sol = false;
for (int i = 2 * n - 1; i >= 0; --i) {
if (T[stk[i]].vis && T[stk[i] ^ 1].vis)
dfs_backward(stk[i]);
}
return no_sol ? vector<bool>() : sol;
}
};
int main() {
freopen("2sat.in", "r", stdin);
freopen("2sat.out", "w", stdout);
int n, m; cin >> n >> m;
TwoSAT sat(n);
while (m--) {
int a, b; cin >> a >> b;
sat.AddEdge(-a, b);
sat.AddEdge(-b, a);
}
auto ret = sat.Solve();
if (ret.empty()) {
cout << -1 << endl;
} else {
for (auto x : ret)
cout << x << " ";
cout << endl;
}
return 0;
}