2-SAT
computational complexity
algorithms
satisfiability problem
graph theory

Algorithm for 2-Satisfiability problem

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

The 2-SAT problem asks whether a CNF formula with exactly two literals per clause is satisfiable.

Example clause: (x1¬x2)(x_1 \lor \neg x_2).

Unlike 3-SAT, 2-SAT is solvable in linear time using strongly connected components (SCCs).

Core Idea: Implication Graph

For each variable x, create two nodes:

  • x
  • ~x

For each clause (ab)(a \lor b), add implications:

  • (¬ab)(\neg a \to b)
  • (¬ba)(\neg b \to a)

After building the graph, compute SCCs.

Satisfiability Condition

The formula is satisfiable iff for every variable x, nodes x and ~x are in different SCCs.

If any variable and its negation fall in the same SCC, the formula is unsatisfiable.

Getting an Assignment

After SCC computation (Kosaraju or Tarjan), assign truth values by SCC topological order:

  • process SCCs in reverse topological order,
  • set a literal true if its SCC appears after its negation SCC.

Python Reference Implementation

python
1def two_sat(num_vars, clauses):
2    # Variables are 1..num_vars. Literal encoding:
3    #  i  -> variable i
4    # -i  -> negation of variable i
5
6    def idx(lit):
7        v = abs(lit) - 1
8        return 2 * v + (0 if lit > 0 else 1)
9
10    def neg(i):
11        return i ^ 1
12
13    n = 2 * num_vars
14    g = [[] for _ in range(n)]
15    rg = [[] for _ in range(n)]
16
17    def add_edge(u, v):
18        g[u].append(v)
19        rg[v].append(u)
20
21    for a, b in clauses:
22        ai, bi = idx(a), idx(b)
23        add_edge(neg(ai), bi)
24        add_edge(neg(bi), ai)
25
26    order = []
27    seen = [False] * n
28
29    def dfs1(u):
30        seen[u] = True
31        for v in g[u]:
32            if not seen[v]:
33                dfs1(v)
34        order.append(u)
35
36    for i in range(n):
37        if not seen[i]:
38            dfs1(i)
39
40    comp = [-1] * n
41
42    def dfs2(u, c):
43        comp[u] = c
44        for v in rg[u]:
45            if comp[v] == -1:
46                dfs2(v, c)
47
48    c = 0
49    for u in reversed(order):
50        if comp[u] == -1:
51            dfs2(u, c)
52            c += 1
53
54    assignment = [False] * (num_vars + 1)
55    for var in range(1, num_vars + 1):
56        t = idx(var)
57        f = idx(-var)
58        if comp[t] == comp[f]:
59            return False, None
60        assignment[var] = comp[t] > comp[f]
61
62    return True, assignment[1:]
63
64
65ok, values = two_sat(
66    3,
67    [
68        (1, -2),   # (x1 v ~x2)
69        (-1, 3),   # (~x1 v x3)
70        (2, -3),   # (x2 v ~x3)
71    ],
72)
73print(ok, values)

Complexity

Let n be variables and m clauses:

  • Vertices: 2n
  • Edges: 2m
  • Time: O(n + m)
  • Space: O(n + m)

Summary

TopicResult
Solver modelImplication graph + SCC
Unsat checkx and ~x in same SCC
ComplexityLinear in graph size

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms