Cod sursa(job #1541989)

Utilizator danny794Dan Danaila danny794 Data 4 decembrie 2015 20:24:27
Problema 2SAT Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.56 kb
#include <bitset>
#include <cstdio>
#include <vector>

#define NMAX (2 * 100000 + 1)
#define INF (1 << 30)

using namespace std;

int n, m;
bitset<NMAX> solution;
bitset<NMAX> onStack;
vector<int> children[NMAX], stack;
vector<vector<vector<int> > > components;
int minim[NMAX], index[NMAX], count;

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

void readInput() {
  int a, b;
  freopen("2sat.in", "r", stdin);
  freopen("2sat.out", "w", stdout);
  scanf("%d %d\n", &n, &m);
  for (int i = 0; i < m; i++) {
    scanf("%d %d\n", &a, &b);
    children[getIndex(-a)].push_back(getIndex(b));
    children[getIndex(-b)].push_back(getIndex(a));
  }
  for (int i = 1; i <= 2 * n; i++) {
    minim[i] = INF;
  }
}

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

void pop(int idx) {
  if (minim[idx] == index[idx]) {
    components.back().push_back(vector<int>());
    int top;
    do {
      top = stack.back();
      stack.pop_back();
      onStack[top] = 0;
      components.back().back().push_back(top);
    } while (top != idx);
  }
}

void visit(int idx) {
  push(idx);
  for (size_t i = 0; i < children[idx].size(); i++) {
    int child = getIndex(children[idx][i]);
    if (minim[child] == INF) {
      visit(child);
      minim[idx] = min(minim[idx], minim[child]);
    } else if (onStack[child]) {
      minim[idx] = min(minim[idx], index[child]);
    }
  }
  pop(idx);
}

void getConnectedComponents() {
  for (int i = 1; i <= 2 * n; i++) {
    if (minim[i] == INF) {
      components.push_back(vector<vector<int> >());
      visit(i);
    }
  }
}

inline bool markNode(int node, int val) {
  if (onStack[node]) {
    return false;
  }
  onStack[node] = 1;
  solution[node] = val;
  return true;
}

bool solve() {
  for (size_t i = 0; i < components.size(); i++) {
    int previous = 1;
    for (size_t j = 0; j < components[i].size(); j++) {
      if (onStack[components[i][j][0]]) {
        previous = solution[components[i][j][0]];
        continue;
      }
      // component not marked
      for (size_t k = 0; k < components[i][j].size(); k++) {
        int node = components[i][j][k];
        if (!markNode(node, previous)) {
          return false;
        }
        node = node > n ? node - n : node + n;
        if (!markNode(node, 1 - previous)) {
          return false;
        }
      }
    }
  }
  return true;
}

int main() {
  readInput();
  getConnectedComponents();
  if (!solve()) {
    printf("-1\n");
  } else {
    for (int i = 1; i <= n; i++) {
      printf("%d ", solution[i] ? 1 : 0);
    }
  }
  return 0;
}