Cod sursa(job #2690826)

Utilizator retrogradLucian Bicsi retrograd Data 26 decembrie 2020 03:52:55
Problema 2SAT Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.99 kb
#include <bits/stdc++.h>

using namespace std;

template<typename T>
struct BiVec { 
  vector<T> v;
  BiVec(int n, T x = {}) : v(2 * n, x) {}
  T& operator[](int i) {
    return v[2 * max(i, ~i) + (i < 0)];
  }
  void resize(int n) { v.resize(2 * n); }
};

struct TwoSat {
  int n;
  BiVec<vector<int>> graph;
  
  TwoSat(int n) : n(n), graph(n) {}
  
  void Implies(int a, int b) {
    graph[a].push_back(b);
    graph[~b].push_back(~a);
  }
  void Either(int a, int b) { Implies(~a, b); }
  void SetValue(int x) { Either(x, x); }
  int AddVar() { graph.resize(++n); return n - 1; } 
  void AtMostOne(const vector<int>& vals) {
    if (vals.size() <= 1) return;
    int cur = ~vals[0];
    for (int i = 2; i < (int)vals.size(); ++i) {
      int nxt = AddVar();
      Either(cur, ~vals[i]);
      Either(cur, nxt);
      Either(~vals[i], nxt);
      cur = ~nxt;
    }
    Either(cur, ~vals[1]);
  }

  vector<int> Solve() {
    BiVec<int> vis(n); int cc = 0;
    vector<int> stk;

    function<void(int)> dfs1 = [&](int node) {
      if (vis[node]) return;
      vis[node] = -1;
      for (auto vec : graph[node])
        dfs1(vec);
      stk.push_back(node);
    };
    function<void(int)> dfs2 = [&](int node) {
      if (vis[node] != -1) return;
      vis[node] = cc;
      for (auto vec : graph[~node])
        dfs2(~vec);
    };
    for (int i = 0; i < n; ++i)
      dfs1(i), dfs1(~i);
    for (int i = 2 * n - 1; i >= 0; --i)
      ++cc, dfs2(stk[i]);
    
    vector<int> ans(n);
    for (int i = 0; i < n; ++i) {
      if (vis[i] == vis[~i]) return {};
      ans[i] = vis[i] > vis[~i];
    }
    return ans;
  }
};

int read() { 
  int x; cin >> x; 
  if (x > 0) --x;
  return x;
}

int main() {
  ifstream cin("2sat.in");
  ofstream cout("2sat.out");
  int n, m; cin >> n >> m;
  TwoSat sat(n);
  for (int i = 0; i < m; ++i) {
    sat.Either(read(), read());
  }
  auto sol = sat.Solve();
  if (sol.empty()) cout << "-1\n";
  else {
    for (int i = 0; i < n; ++i)
      cout << sol[i] << " ";
    cout << endl;
  }
  return 0;
}