Cod sursa(job #1833930)

Utilizator TincaMateiTinca Matei TincaMatei Data 23 decembrie 2016 15:42:33
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <cstdio>

const int MAX_N = 200000;
const int MAX_M = 400000;
int last[1+MAX_N], next[1+MAX_M], mc[1+MAX_M];
bool val[1+MAX_N];
bool tog[1+MAX_N];
int index[1+MAX_N], low[1+MAX_N];
int ind;
int st[1+MAX_N], top;
bool in[1+MAX_N];

inline int min(int a, int b) {
  if(a < b)
    return a;
  return b;
}

inline int trans(int x) {
  if(x < 0)
    return (-x - 1) * 2 + 1;
  return (x - 1) * 2;
}

inline void addM(int a, int b, int id) {
  mc[id] = b;
  next[id] = last[a];
  last[a] = id;
}

inline void toggle(int node) {
  if(!tog[node]) {
    val[node] = true;
    val[node ^ 1] = false;
    tog[node] = true;
    tog[node ^ 1] = true;
  }
}

void ctc(int node) {
  ++ind;
  low[node] = index[node] = ind;
  st[top] = node; ++top;
  in[node] = true;

  int i = last[node];
  while(i != 0) {
    if(index[mc[i]] == 0) {
      ctc(mc[i]);
      low[node] = min(low[node], low[mc[i]]);
    } else if(in[mc[i]])
      low[node] = min(low[node], low[mc[i]]);
    i = next[i];
  }

  if(index[node] == low[node]) {
    while(st[top - 1] != node) {
      low[st[top - 1]] = low[node];
      toggle(st[top - 1]);
      in[st[top - 1]] = false;
      --top;
    }
    in[node] = false;
    --top;
    toggle(node);
  }
}

int main() {
  int n, m, a, b;
  FILE *fin = fopen("2sat.in", "r");
  fscanf(fin, "%d%d", &n, &m);
  for(int i = 0; i < m; ++i) {
    fscanf(fin, "%d%d", &a, &b);
    a = trans(a);
    b = trans(b);
    addM(a ^ 1, b, i * 2 + 1);
    addM(b ^ 1, a, i * 2 + 2);
  }
  fclose(fin);

  for(int i = 0; i < 2 * n; ++i)
    if(index[i] == 0)
      ctc(i);

  bool satana = false;
  for(int i = 0; i < n; i++)
    if(low[i * 2] == low[(i * 2) ^ 1])
      satana = true;

  FILE *fout = fopen("2sat.out", "w");
  if(satana)
    fprintf(fout, "-1");
  else
    for(int i = 0; i < n; ++i)
      fprintf(fout, "%d ", val[i * 2]);
  fclose(fout);
  return 0;
}