Advertisement
slash0t

2sat (not my)

Mar 16th, 2025
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.91 KB | None | 0 0
  1. struct two_sat {
  2.     int n;
  3.     vector<vector<int>> g, gr;
  4.     vector<int> comp, topological_order, answer;
  5.     vector<bool> vis;
  6.  
  7.     two_sat() {}
  8.  
  9.     two_sat(int _n) { init(_n); }
  10.  
  11.     void init(int _n) {
  12.         n = _n;
  13.         g.assign(2 * n, vector<int>());
  14.         gr.assign(2 * n, vector<int>());
  15.         comp.resize(2 * n);
  16.         vis.resize(2 * n);
  17.         answer.resize(2 * n);
  18.     }
  19.  
  20.     void add_edge(int u, int v) {
  21.         g[u].push_back(v);
  22.         gr[v].push_back(u);
  23.     }
  24.  
  25.     // At least one of them is true
  26.     void add_clause_or(int i, bool f, int j, bool g) {
  27.         add_edge(i + (f ? n : 0), j + (g ? 0 : n));
  28.         add_edge(j + (g ? n : 0), i + (f ? 0 : n));
  29.     }
  30.  
  31.     // Only one of them is true
  32.     void add_clause_xor(int i, bool f, int j, bool g) {
  33.         add_clause_or(i, f, j, g);
  34.         add_clause_or(i, !f, j, !g);
  35.     }
  36.  
  37.     // Both of them have the same value
  38.     void add_clause_and(int i, bool f, int j, bool g) {
  39.         add_clause_xor(i, !f, j, g);
  40.     }
  41.  
  42.     void dfs(int u) {
  43.         vis[u] = true;
  44.  
  45.         for (const auto& v : g[u])
  46.             if (!vis[v]) dfs(v);
  47.  
  48.         topological_order.push_back(u);
  49.     }
  50.  
  51.     void scc(int u, int id) {
  52.         vis[u] = true;
  53.         comp[u] = id;
  54.  
  55.         for (const auto& v : gr[u])
  56.             if (!vis[v]) scc(v, id);
  57.     }
  58.  
  59.     bool satisfiable() {
  60.         fill(vis.begin(), vis.end(), false);
  61.  
  62.         for (int i = 0; i < 2 * n; i++)
  63.             if (!vis[i]) dfs(i);
  64.  
  65.         fill(vis.begin(), vis.end(), false);
  66.         reverse(topological_order.begin(), topological_order.end());
  67.  
  68.         int id = 0;
  69.         for (const auto& v : topological_order)
  70.             if (!vis[v]) scc(v, id++);
  71.  
  72.         for (int i = 0; i < n; i++) {
  73.             if (comp[i] == comp[i + n]) return false;
  74.             answer[i] = (comp[i] > comp[i + n] ? 1 : 0);
  75.         }
  76.  
  77.         return true;
  78.     }
  79. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement