Cod sursa(job #1489809)

Utilizator salam1Florin Salam salam1 Data 22 septembrie 2015 02:50:33
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#include <cstdio>
#include <vector>
using namespace std;
 
struct TwoSatSolver {
  int n;
  vector<vector<int>> &G;
  vector<bool> mark;
  vector<int> currIter, twoSatSol;
  bool isTwoSat;
 
public: 
  TwoSatSolver(int _n, vector<vector<int>> &_G): n(_n), G(_G) { }
 
  void prepareTwoSat();
 
private:
  inline int negNode(int node) {
    return node > n ? node - n : node + n;
  }
 
  bool isValid(int, bool);
};
 
void TwoSatSolver::prepareTwoSat() {
  mark.assign(2 * n + 1, false);
  twoSatSol.assign(2 * n + 1, 0);
  currIter.clear();
  isTwoSat = true;
 
  for (int i = 1; i <= n; i++) {
    if (!mark[i]) {
      currIter.clear();
      if (!isValid(i, false)) {
        for (auto x: currIter) {
          mark[x] = mark[negNode(x)] = false;
        }
        currIter.clear();
        if (!isValid(i, true)) {
          isTwoSat = false;
          break;
        }
      }
    }
  }
}
 
bool TwoSatSolver::isValid(int node, bool value) {
  mark[node] = mark[negNode(node)] = true;
  currIter.push_back(node);
  twoSatSol[node] = value; twoSatSol[negNode(node)] = value ^ 1;
 
  if (value) node = negNode(node);
  bool sol = true;
  for (auto x: G[node]) {
    if (mark[x] && !twoSatSol[x]) {
      return false;
    }
    if (!mark[x]) {
      sol &= isValid(x, true);
    }
  }
 
  return sol;
}
 
// End of TwoSatSolver class
 
int n, m;
vector<vector<int>> G;
 
inline int nodeIdx(int node) {
  return node < 0 ? -node + n : node;
}
 
inline int negNode(int node) {
  return node > n ? node - n : node + n;
}
 
void addOrRelation(int x, int y) {
  G[x].push_back(y);
  G[y].push_back(x);
}
 
void read() {
  scanf("%d%d", &n, &m);
  G.reserve(2 * n + 1);
  int x, y;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &x, &y);
    x = nodeIdx(x); y = nodeIdx(y);
    addOrRelation(x, y);
  }
}
 
void solve() {
  TwoSatSolver* twoSatSolver = new TwoSatSolver(n, G);
  twoSatSolver -> prepareTwoSat();
  if (twoSatSolver -> isTwoSat) {
    for (int i = 1; i <= n; i++) {
      printf("%d", twoSatSolver -> twoSatSol[i]);
      if (i < n) printf(" ");
    }
  } else {
    printf("-1\n");
  }
}
 
int main() {
  freopen("2sat.in", "r", stdin);
  freopen("2sat.out", "w", stdout);
 
  read();
  solve();
  return 0;
}