Cod sursa(job #2119946)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 1 februarie 2018 19:30:18
Problema 2SAT Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.87 kb
#include <fstream>
#include <vector>
#include <stack>
#include <map>
#include <queue>

using namespace std;

ifstream cin ("2sat.in");
ofstream cout ("2sat.out");

void Dfs1 (int cur_node, vector < vector < int > > &gr, 
    vector < bool > &used, stack < int > &stk) {

  used[cur_node] = true;
  for (int x : gr[cur_node]) {
    if (used[x]) {
      continue;
    }

    Dfs1 (x, gr, used, stk);
  }

  stk.push (cur_node);
}

void Dfs2 (int cur_node, vector < vector < int > > &gr, 
    vector < bool > &used, vector < int > &ctc, int &cnt) {

  ctc[cur_node] = cnt;
  used[cur_node] = true;
 
  for (int x : gr[cur_node]) {
    if (used[x]) {
      continue;
    }

    Dfs2 (x, gr, used, ctc, cnt);
  }
}

int main () {
  
  ios::sync_with_stdio (false);
  cin.tie (0); cout.tie (0);

  int n, m;
  cin >> n >> m;
  
  const int SIZE = 2 * n + 1;

  vector < int > opp (SIZE);
  for (int i = 1; i <= n; ++ i) {
    opp[i] = i + n;
    opp[i + n] = i;
  }

  vector < vector < int > > gr (SIZE), inv (SIZE);

  for (int i = 1; i <= m; ++ i) {
    int x, y;
    cin >> x >> y;

    if (x < 0) {
      x = opp[(-1) * x];
    }

    if (y < 0) {
      y = opp[(-1) * y];
    }
  
    gr[opp[x]].push_back (y);
    gr[opp[y]].push_back (x);

    inv[y].push_back (opp[x]);
    inv[x].push_back (opp[y]);
  }
  
  stack < int > stk;
  vector < int > ctc (SIZE);
  vector < bool > used (SIZE); 

  for (int i = 1; i < SIZE; ++ i) {
    if (used[i]) {
      continue;
    }

    Dfs1 (i, gr, used, stk);
  }

  vector < bool > used2 (SIZE);

  int nr_of_ctc = 0;
  while (not stk.empty ()) {

    int cur = stk.top ();
    stk.pop ();

    if (used2[cur]) {
      continue;
    }
  
    ++ nr_of_ctc;
    Dfs2 (cur, inv, used2, ctc, nr_of_ctc);
  }
  
  vector < int > lvl (nr_of_ctc + 1);
  map < pair < int, int >, bool > linked;
  vector < vector < int > > ctc_gr (nr_of_ctc + 1);

  for (int i = 1; i <= 2 * n; ++ i) {
    if (ctc[i] == ctc[opp[i]]) {
      cout << -1 << '\n';
      return 0;
    }

    for (int x : gr[i]) {
      if (ctc[x] != ctc[i]) {
        if (linked[{ctc[i], ctc[x]}] or linked[{ctc[x], ctc[i]}]) {
          continue;
        }

        ++ lvl[ctc[x]];
        ctc_gr[ctc[i]].push_back (ctc[x]);
        linked[{ctc[i], ctc[x]}] = true;
      }
    }
  }

  queue < int > q;
  vector < int > opp_ctc (nr_of_ctc + 1);
  for (int i = 1; i <= n; ++ i) {
    opp_ctc[ctc[i]] = ctc[opp[i]];
    opp_ctc[ctc[opp[i]]] = ctc[i];
  }

  for (int i = 1; i <= nr_of_ctc; ++ i) {
    if (lvl[i] == 0) {
      q.push (i);
    }
  }
  
  vector < int > val (nr_of_ctc + 1, -1);

  while (not q.empty ()) {

    int cur = q.front ();
    q.pop ();
    
    if (val[cur] != -1) {
      continue;
    }

    val[cur] = 0;
    val[opp_ctc[cur]] = 1;

    for (int x : ctc_gr[cur]) {
      if (-- lvl[x] == 0) {
        q.push (x);
      }
    }
  }
  
  for (int i = 1; i <= n; ++ i) {
    cout << val[ctc[i]] << ' ';
  }
}