Cod sursa(job #1489808)

Utilizator salam1Florin Salam salam1 Data 22 septembrie 2015 02:49:15
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb
#include <cstdio>
#include <vector>
using namespace std;

int n, m;
vector<vector<int>> G;
vector<bool> mark;
vector<int> currIter, twoSatSol;
bool isTwoSat;

inline int nodeIdx(int node) {
  return node < 0 ? -node + n : node;
}

inline int negNode(int node) {
  return node > n ? node - n : node + n;
}

bool isValid(int, bool);

void 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 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;
}

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() {
  prepareTwoSat();
  if (isTwoSat) {
    for (int i = 1; i <= n; i++) {
      printf("%d", 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;
}