-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy path2SAT.cpp
More file actions
77 lines (65 loc) · 2.2 KB
/
2SAT.cpp
File metadata and controls
77 lines (65 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <bits/stdc++.h>
using namespace std;
struct TwoSat {
int N;
vector<vector<int>> E;
TwoSat(int N) : N(N), E(2 * N) {}
inline int eval(int u) const{ return u < 0 ? ((~u)+N)%(2*N) : u; }
void add_or(int u, int v){
E[eval(~u)].push_back(eval(v));
E[eval(~v)].push_back(eval(u));
}
void add_nand(int u, int v) {
E[eval(u)].push_back(eval(~v));
E[eval(v)].push_back(eval(~u));
}
void set_true (int u){ E[eval(~u)].push_back(eval(u)); }
void set_false(int u){ set_true(~u); }
void add_imply(int u, int v){ E[eval(u)].push_back(eval(v)); }
void add_and (int u, int v){ set_true(u); set_true(v); }
void add_nor (int u, int v){ add_and(~u, ~v); }
void add_xor (int u, int v){ add_or(u, v); add_nand(u, v); }
void add_xnor (int u, int v){ add_xor(u, ~v); }
vector<bool> solve() {
vector<bool> ans(N);
auto scc = tarjan();
for (int u = 0; u < N; u++)
if(scc[u] == scc[u+N]) return {}; //false
else ans[u] = scc[u+N] > scc[u];
return ans; //true
}
private:
vector<int> tarjan() {
vector<int> low(2*N), pre(2*N, -1), scc(2*N, -1), st;
int clk = 0, ncomps = 0;
function<void(int)> dfs = [&](int u){
pre[u] = low[u] = clk++;
st.push_back(u);
for(auto v : E[u])
if(pre[v] == -1) dfs(v), low[u] = min(low[u], low[v]);
else
if(scc[v] == -1) low[u] = min(low[u], pre[v]);
if(low[u] == pre[u]){
int v = -1;
while(v != u) scc[v = st.back()] = ncomps, st.pop_back();
ncomps++;
}
};
for(int u=0; u < 2*N; u++)
if(pre[u] == -1)
dfs(u);
return scc; //tarjan SCCs order is the reverse of topoSort, so (u->v if scc[v] <= scc[u])
}
};
/*LATEX_DESC_BEGIN***************************
**2 SAT - Two Satisfiability Problem**
Retorna uma valoração verdadeira se possível ou um vetor vazio se impossível;
inverso de u = ~u
@\vspace{0pt}\begin{center}\begin{tabular}{|| c c || c | c | c | c | c | c | c ||}
A & B & OR & AND & NOR & NAND & XOR & XNOR & IMPLY \\
0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 1 \\
0 & 1 & 1 & 0 & 0 & 1 & 1 & 0 & 1 \\
1 & 0 & 1 & 0 & 0 & 1 & 1 & 0 & 0 \\
1 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 1 \\
\end{tabular}\end{center}@
*****************************LATEX_DESC_END*/