2-SAT
Satisfiability of boolean formulas with 2 literals per clause
2-SAT Algorithm
Definition
is a 2-CNF formula with clauses and variables, where each clause has exactly 2 literals.
A literal is either a variable or its negation .
2-SAT Algorithm
(Satisfiability of boolean formulas with 2 literals per clause)
CNF is AND of ORs.
Given a 2-CNF formula, construct an implication graph.
Each variable has two nodes: and .
For each clause , add edges and .
The formula is satisfiable if and only if and are in different SCCs.
Use Kosaraju's or Tarjan's algorithm to find SCCs.
k-SAT is NP-complete for , where input is in CNF with literals per clause.
Construction
Implementation of the algorithm:
vector<vector<int>> e;
vector<bool> ans;
void build_implication_graph(int n, int m) {
e.assign(2 * n + 1, {});
for (int i = 1; i <= m; i++) {
int a, b; // literals in clause (a or b), read from input
bool is_neg_a, is_neg_b; // read from input
int ya = is_neg_a ? a + n : a; // node for a
int yb = is_neg_b ? b + n : b; // node for b
int na = is_neg_a ? a : a + n; // node for ¬a
int nb = is_neg_b ? b : b + n; // node for ¬b
e[na].push_back(yb); // ¬a -> b
e[nb].push_back(ya); // ¬b -> a
}
}
bool find_answer(int n) {
kosaraju(2 * n); // find SCCs on all 2n nodes; sccid follows the topological order
for (int i = 1; i <= n; i++) {
if (sccid[i] == sccid[i + n]) // x and ¬x in same SCC
return false; // unsatisfiable
}
ans.assign(n + 1, false);
for (int i = 1; i <= n; i++)
ans[i] = sccid[i] > sccid[i + n]; // x is true iff x comes after ¬x in topological order
return true; // satisfiable
}