-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTwoSAT.cpp
88 lines (78 loc) · 2.3 KB
/
TwoSAT.cpp
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
78
79
80
81
82
83
84
85
86
87
88
struct TwoSat {
int n;
int NUM_VERTICES, id;
vector<int> arr;
vector<vector<int>> adj;
vector<bool> mark;
TwoSat(int n) : n(n), adj(2 * n + 2), NUM_VERTICES(2 * n), mark(2 * n + 2), arr(2 * n + 2) {}
inline bool dfs(int node) {
if (mark[node ^ 1]) {
return false;
}
if (mark[node]) {
return true;
}
mark[node] = true;
arr[id++] = node;
for (int i = 0; i < (int) adj[node].size(); i++) {
if (!dfs(adj[node][i])) {
return false;
}
}
return true;
}
// Adds the clause (u or v) to the set of clauses
inline void addOr(int u, int v) {
adj[u ^ 1].emplace_back(v);
adj[v ^ 1].emplace_back(u);
}
// Adds the clause (u == v) to the set of clauses
inline void addEquivalent(int u, int v) {
adj[u].emplace_back(v);
adj[v].emplace_back(u);
adj[u ^ 1].emplace_back(v ^ 1);
adj[v ^ 1].emplace_back(u ^ 1);
}
// Adds the clause (u xor v) to the set of clauses
inline void addXor(int u, int v) {
addOr(u, v);
addOr(u ^ 1, v ^ 1);
}
// Forces variable (u) to be true
inline void forceTrue(int u) {
adj[u ^ 1].emplace_back(u);
}
// Forces variable (u) to be false
inline void forceFalse(int u) {
adj[u].emplace_back(u ^ 1);
}
// Adds the clause (u and v) to the set of clauses
inline void addAnd(int u, int v) {
forceTrue(u);
forceTrue(v);
}
inline void addImplication(int u, int v) {
adj[u].emplace_back(v);
}
// Returns true if a solution exists.
inline bool solve() {
for (int i = 0; i < NUM_VERTICES; i++) {
sort(adj[i].begin(), adj[i].end());
adj[i].resize(unique(adj[i].begin(), adj[i].end()) - adj[i].begin());
}
for (int i = 0; i < NUM_VERTICES; i += 2) {
if ((!mark[i]) && (!mark[i + 1])) {
id = 0;
if(!dfs(i)) {
while (id > 0) {
mark[arr[--id]] = false;
}
if(!dfs(i + 1)) {
return false;
}
}
}
}
return true;
}
};