Cod sursa(job #3238506)

Utilizator Traian_7109Traian Mihai Danciu Traian_7109 Data 25 iulie 2024 23:17:14
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include <stdio.h>
#include <vector>

#define MAXN 200000

static inline int min(int a, int b) {
  return a < b ? a : b;
}

std::vector<int> g[MAXN];

struct Tarjan {
  int idx[MAXN], lowlink[MAXN], ptr, instack[MAXN], stiva[MAXN], sp,
                                          comp[MAXN], ncomp;
  
  void dfs(int nod) {
    int i, aux;
    
    lowlink[nod] = idx[nod] = ++ptr;
    instack[nod] = 1;
    stiva[sp++] = nod;
    
    for(i = 0; i < (int)g[nod].size(); i++) {
      if(idx[g[nod][i]] == 0) {
        dfs(g[nod][i]);
        lowlink[nod] = min(lowlink[nod], lowlink[g[nod][i]]);
      } else if(instack[g[nod][i]]) {
        lowlink[nod] = min(lowlink[nod], lowlink[g[nod][i]]);
      }
    }
    
    if(idx[nod] == lowlink[nod]) {
      do {
        aux = stiva[--sp];
        instack[aux] = 0;
        comp[aux] = ncomp;
      } while(aux != nod);
      ncomp++;
    }
  }
  
  int solve(int n) {
    int i;
    
    for(i = 0; i < n; i++) {
      idx[i] = instack[i] = 0;
    }
    ptr = sp = ncomp = 0;
    for(i = 0; i < n; i++) {
      if(idx[i] == 0) {
        dfs(i);
      }
    }
    return ncomp;
  }
};


struct TwoSat {
  Tarjan ctc;
  int ans[MAXN];
  
  void clear(int n) {
    int i;
    
    for(i = 0; i < 2 * n; i++) {
      g[i].clear();
    }
  }
  
  inline void implica(int u, int v) {
    g[u].push_back(v);
  }
  
  inline void sau(int u, int v) {
    implica(u ^ 1, v);
    implica(v ^ 1, u);
  }
  
  int solve(int n) {
    int i;
    
    ctc.solve(2 * n);
    i = 0;
    while(i < n && ctc.comp[2 * i] != ctc.comp[2 * i + 1]) {
      ans[i] = ctc.comp[2 * i] < ctc.comp[2 * i + 1];
      i++;
    }
    
    return i == n;
  }
} ds;

int main() {
  int n, m, i, u, v;
  
  #ifndef LOCAL
    freopen("2sat.in", "r", stdin);
    freopen("2sat.out", "w", stdout);
  #endif
  
  scanf("%d%d", &n, &m);
  ds.clear(n);
  for(i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    
    if(u < 0) {
      u = 2 * (-u) - 1;
    } else {
      u = 2 * (u - 1);
    }
    if(v < 0) {
      v = 2 * (-v) - 1;
    } else {
      v = 2 * (v - 1);
    }
    
    ds.sau(u, v);
  }
  
  if(ds.solve(n)) {
    for(i = 0; i < n; i++) {
      printf("%d ", ds.ans[i]);
    }
    fputc('\n', stdout);
  } else {
    printf("-1\n");
  }
  
  return 0;
}