Cod sursa(job #1550825)

Utilizator danny794Dan Danaila danny794 Data 14 decembrie 2015 19:29:06
Problema 2SAT Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 kb
#include <bitset>
#include <vector>

#define NMAX 100001

using namespace std;

const int INF = 1 << 30;
int n, m;
vector<int> edges[NMAX], stack;
bitset<NMAX> onStack, solution, marked;
int minim[NMAX], level[NMAX], count;
bool wrong;

inline int index(int idx) {
  return idx > 0 ? idx : n - idx;
}

inline int adjacent(int idx) {
  return idx > n ? idx - n : idx + n;
}

void read() {
  freopen("2sat.in", "r", stdin);
  freopen("2sat.out", "w", stdout);
  scanf("%d %d\n", &n, &m);
  wrong = false;
  int a, b;
  while (m-- > 0) {
    scanf("%d %d", &a, &b);
    edges[index(-a)].push_back(index(b));
    edges[index(-b)].push_back(index(a));
  }
  for (int i = 1; i <= (n << 1); i++) {
    level[i] = INF;
  }
}

void push(int idx) {
  onStack[idx] = true;
  minim[idx] = level[idx] = ++count;
  stack.push_back(idx);
}

inline void mark(int idx, bool value) {
  if (marked[idx] && solution[idx] != value) {
    wrong = true;
  }
  solution[idx] = value;
  marked[idx] = true;
}

void pop(int idx, bool value) {
  if (minim[idx] == level[idx]) {
    int top;
    do {
      top = stack.back();
      onStack[top] = false;
      mark(top, value);
      mark(adjacent(top), !value);
      stack.pop_back();
    } while (top != idx);
  }
}

bool visit(int idx) {
  push(idx);
  bool value = true;
  for (size_t i = 0; i < edges[idx].size(); i++) {
    int child = edges[idx][i];
    if (level[child] == INF) {
      value &= visit(child);
      minim[idx] = min(minim[idx], minim[child]);
    } else if (onStack[child]) {
      minim[idx] = min(minim[idx], level[child]);
      value &= true;
    } else {
      value &= solution[child];
    }
  }
  if (marked[idx]) {
    value &= solution[idx];
  }
  pop(idx, value);
  return value;
}

int main() {
  read();
  for (int i = 1; i <= (n << 1); i++) {
    if (level[i] == INF) {
      visit(i);
    }
  }
  if (wrong) {
    printf("-1");
  } else {
    for (int i = 1; i <= n; i++) {
      printf("%d ", solution[i] ? 1 : 0);
    }
  }
  return 0;
}