Cod sursa(job #1489795)

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

struct Graph {
  int n, postIdx;
  vector<vector<int>> &G, GT;
  vector<bool> mark;
  vector<int> postOrder, twoSatSol;
  bool isTwoSat;

public: 
  Graph(int _n, vector<vector<int>> &_G): n(_n), G(_G) { }

  void prepareTwoSat();

private:
  void dfs1(int);

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

  void dfs2(int);
};

void Graph::prepareTwoSat() {
  GT.resize(2 * n + 1);
  for (int i = 1; i <= 2 * n; i++) {
    for (auto x: G[i]) {
      GT[x].push_back(i);
    }
  }

  mark.assign(2 * n + 1, false);
  postOrder.reserve(2 * n + 1);
  postIdx = 0;
  for (int i = 1; i <= 2 * n; i++) {
    if (!mark[i]) {
      dfs1(i);
    }
  }

  mark.assign(2 * n + 1, false);
  twoSatSol.assign(2 * n + 1, 0);
  isTwoSat = true;

  for (int i = postIdx; i >= 1; i--) {
    int currNode = postOrder[i];
    if (!mark[currNode] && !mark[negNode(currNode)]) {
      dfs2(currNode);
    }
  }
}

void Graph::dfs1(int node) {
  mark[node] = true;
  for (auto x: G[node])
    if (!mark[x]) {
      dfs1(x);
    }
  postOrder[++postIdx] = node;
}

void Graph::dfs2(int node) {
  mark[node] = true;
  if (mark[negNode(node)]) {
    isTwoSat = false;
  }
  twoSatSol[negNode(node)] = 1;
  for (auto x: GT[node])
    if (!mark[x]) {
      dfs2(x);
    }
}
// End of Graph 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[negNode(x)].push_back(y);
  G[negNode(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() {
  Graph* graph = new Graph(n, G);
  graph -> prepareTwoSat();
  if (graph -> isTwoSat) {
    for (int i = 1; i <= n; i++) {
      printf("%d", graph -> 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;
}