Pagini recente » Cod sursa (job #2597220) | Cod sursa (job #1854847) | Cod sursa (job #38255) | Cod sursa (job #183612) | Cod sursa (job #1695042)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cassert>
using namespace std;
class twoSatSolver {
private:
int N;
vector<vector<int>> G;
vector<vector<int>> GT;
void addEdge(int x, int y) {
G[x].push_back(y);
G[y].push_back(x);
}
public:
inline int negate(int node){
return node > N ? node - N : node + N;
}
twoSatSolver(int _N) : N(_N) {
G.assign(2 * N + 1, vector<int>());
GT.assign(2 * N + 1, vector<int>());
}
void addOrEdge(int x, int y) {
addEdge(negate(x), y);
addEdge(negate(y), x);
}
void dfs1(int node, vector<bool>& mark, vector<int>& topoSort) {
mark[node] = true;
for (auto& x: G[node]) {
if (!mark[x]) {
dfs1(x, mark, topoSort);
}
}
topoSort.push_back(node);
}
bool dfs2(int node, vector<bool>& mark, vector<bool>& sol) {
if (sol[node]) {
return false;
}
sol[negate(node)] = true;
mark[node] = true;
bool success = true;
for (auto& x: GT[node]) {
if (!mark[x]) {
success &= dfs2(x, mark, sol);
}
}
return success;
}
vector<bool> solve2SAT() {
vector<bool> mark(2 * N + 1, false);
vector<int> topoSort;
topoSort.reserve(2 * N + 1);
for (int i = 1; i <= 2 * N; i++) {
if (!mark[i]) {
dfs1(i, mark, topoSort);
}
}
reverse(topoSort.begin(), topoSort.end());
mark.assign(2 * N + 1, false);
bool success = true;
vector<bool> sol(2 * N + 1, false);
for (auto& node: topoSort) {
if (!mark[node] && !mark[negate(node)]) {
success &= dfs2(node, mark, sol);
}
}
assert(success);
vector<bool> result(sol.begin(), sol.begin() + N + 1);
return result;
}
};
twoSatSolver* solver;
int N, M;
void read() {
scanf("%d%d", &N, &M);
solver = new twoSatSolver(N);
int x, y, col;
for (int i = 1; i <= M; i++) {
scanf("%d%d%d", &x, &y, &col);
switch (col) {
case 0:
// x | y
solver -> addOrEdge(x, y);
break;
case 1:
// ~x | ~y
solver -> addOrEdge(solver -> negate(x), solver -> negate(y));
break;
case 2:
// x <-> y = (x -> y) ^ (y -> x) = (~x | y) ^ (~y | x)
solver -> addOrEdge(solver -> negate(x), y);
solver -> addOrEdge(solver -> negate(y), x);
break;
}
}
}
void solve() {
vector<bool> result = solver -> solve2SAT();
for (int i = 1; i <= N; i++) {
printf("%d ", result[i] ? 1 : 0);
}
printf("\n");
}
int main() {
freopen("andrei.in", "r", stdin);
freopen("andrei.out", "w", stdout);
read();
solve();
return 0;
}