Cod sursa(job #2294653)

Utilizator retrogradLucian Bicsi retrograd Data 2 decembrie 2018 17:30:05
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <bits/stdc++.h>
 
using namespace std;
 
const int MAX_N = 100000;
const int MAX_M = 200000;
const int NIL = -1;
 
struct List {
    int v;
    int next;
};
 
List buff[2 * MAX_M];
int head[2 * MAX_N];
 
bool onStack[2 * MAX_N];
int st[2 * MAX_N], vf;
int ptr[2 * MAX_N], freePtr;
 
List CTC[2 * MAX_N];
int ctcHead[2 * MAX_N];
int numCTC, ctcPtr;
 
bool attribute[2 * MAX_N];
 
void addArc(int u, int v, int pos) {
    buff[pos].v = v;
    buff[pos].next = head[u];
    head[u] = pos;
}
 
int tarjan(int u) {
    onStack[u] = true;
    st[vf++] = u;
    int minPtr = ptr[u] = freePtr++;
 
    for (int i = head[u]; i != NIL; i = buff[i].next) {
        int v = buff[i].v;
        if (ptr[v] == NIL) {
            minPtr = min(minPtr, tarjan(v));
        } else if (onStack[v]) {
            minPtr = min(minPtr, ptr[v]);
        }
    }
 
    if (ptr[u] == minPtr) {
        int v;
        ctcHead[numCTC] = NIL;
        do {
            v = st[--vf];
            onStack[v] = false;
            CTC[ctcPtr].v = v;
            CTC[ctcPtr].next = ctcHead[numCTC];
            ctcHead[numCTC] = ctcPtr++;
        } while (v != u);
        ++ numCTC;
    }
    return minPtr;
}
 
int main() {
    ifstream cin("2sat.in");
    ofstream cout("2sat.out");
    int n, m; cin >> n >> m; 
 
    memset(head, NIL, 4 * 2 * n);
    memset(ptr, NIL, 4 * 2 * n);
 
    for (int i = 0; i < m; ++ i) {
        int u, v; cin >> u >> v;
        u = ((u ^ ((u ^ -u) & -(u < 0))) << 1) - 1 - (u > 0);
        v = ((v ^ ((v ^ -v) & -(v < 0))) << 1) - 1 - (v > 0);
        addArc(u ^ 1, v, 2 * i);
        addArc(v ^ 1, u, 2 * i + 1);
    }
    fclose(stdin);
 
    for (int i = 0; i < (n << 1); ++ i) {
        if (ptr[i] == NIL) {
            tarjan(i);
        }
    }
 
    for (int i = numCTC - 1; i >= 0; -- i)
        if (!attribute[CTC[ctcHead[i]].v])
            for (int j = ctcHead[i]; j != NIL; j = CTC[j].next)
                attribute[CTC[j].v ^ 1] = 1;
 
    int i = 0;
    while (i < n && (attribute[i << 1] != attribute[(i << 1) | 1])) {
        ++ i;
    }
    if (i != n) {
        cout << -1 << endl;
    } else {
        for (int i = 0; i < n; ++ i) {
            cout << attribute[i << 1] << " ";
        }
    }
 
    return 0;
}