Skip to content

2-SAT

Give a series of logical statements and it tells you if they're consistent and gives you a solution.

Code

2-SAT
// TwoSat {{{
struct TwoSat {
  int N;
  vector<vector<int>> G;
  TwoSat(int N) : N(N), G(2*N) {}

  int neg(int u) { return u + ((u < N) ? N : -N); }
  void add_or(int v, int u) {
    G[neg(v)].push_back(u);
    G[neg(u)].push_back(v);
  }
  void add_diff(int v, int u) {
    add_or(v, u);
    add_or(neg(v), neg(u));
  }
  void add_impl(int v, int u) {
    add_or(neg(v), u);
  }
  void add_same(int v, int u) {
    add_impl(v, u);
    add_impl(neg(v), neg(u));
  }
  void add_true(int v) {
    add_or(v, v);
  }
  void add_false(int v) {
    add_or(neg(v), neg(v));
  };

  // Assumes Kosaraju returns components in topological ordering v -> u implies scc[v] <= scc[u]
  pair<bool, vector<bool>> solve() {
    vector<bool> res(N);
    auto scc = Kosaraju(G).comp;
    for (int i = 0; i < N; i++) {
      if (scc[i] == scc[neg(i)]) return {false, {}};
      res[i] = scc[i] < scc[neg(i)];
    }
    return {true, res};
  }
};
//}}}