Cod sursa(job #1542480)

Utilizator dan.marculetFII MarculetDan dan.marculet Data 5 decembrie 2015 13:45:30
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.89 kb
#include <stdio.h>
#include <stdlib.h>

int n, m;
int *l, lidx;
int **a1, **a2, *k1, *k2;
int *c, **cc, *scc;
bool *v;
int *cval;
bool sat;

void init() {
    a1 = (int**)calloc(2 * n, sizeof(int*));
    a2 = (int**)calloc(2 * n, sizeof(int*));
    l = (int*)calloc(2 * n, sizeof(int));
    k1 = (int*)calloc(2 * n, sizeof(int));
    k2 = (int*)calloc(2 * n, sizeof(int));
    c = (int*)calloc(2 * n, sizeof(int));
    v = (bool*)calloc(2 * n, sizeof(bool));
    cval = (int*)calloc(2 * n, sizeof(int));
}

int minus(int x) {
    return 2 * n - x - 1;
}

void getInput() {
    int i, x, y, nodx, nody, modif;
    scanf("%d %d", &n, &m);
    init();

    for (i = 0; i < m; ++i) {
        // x V y
        scanf("%d %d", &x, &y);

        // cele pozitive decrementate (un fel de c2)
        nodx = n + x - (x>0 ? 1 : 0);
        nody = n + y - (y > 0 ? 1 : 0);

        // !x -> y in G2
        modif = minus(nodx);
        a2[modif] = (int*)realloc(a2[modif], (k2[modif] + 1)*sizeof(int));
        a2[modif][k2[modif]++] = nody;

        // !y -> x in G2
        modif = minus(nody);
        a2[modif] = (int*)realloc(a2[modif], (k2[modif] + 1)*sizeof(int));
        a2[modif][k2[modif]++] = nodx;

        // y -> !x in G1
        modif = nody;
        a1[modif] = (int*)realloc(a1[modif], (k1[modif] + 1)*sizeof(int));
        a1[modif][k1[modif]++] = minus(nodx);

        // x -> !y in G1
        modif = nodx;
        a1[modif] = (int*)realloc(a1[modif], (k1[modif] + 1)*sizeof(int));
        a1[modif][k1[modif]++] = minus(nody);
    }
}

void dfs1(int x) {
    v[x] = true;
    for (int i = 0; i < k1[x]; ++i)
        if (!v[a1[x][i]])
            dfs1(a1[x][i]);
    l[--lidx] = x;
}

void dfs2(int x, int& comp) {
    c[x] = comp;
    for (int i = 0; i < k2[x]; ++i)
        if (!c[a2[x][i]])
            dfs2(a2[x][i], comp);
}

int main() {
    freopen("2sat.in", "r", stdin);
    freopen("2sat.out", "w", stdout);
    int i, j, comp = 0;

    getInput();
    /*for (i = 0; i < 2 * n; ++i) {
        printf("Lista lui %d: ", i);
        for (j = 0; j < k2[i]; ++j)
            printf("%d ", a2[i][j]);
        printf("\n");
    }*/

    lidx = 2 * n;
    for (i = 0; i < 2 * n; ++i)
        if (!v[i])
            dfs1(i);

    /*for (i = 0; i < 2 * n; ++i)
        printf("%2d ", l[i]);
    printf("\n");*/

    for (i = 0; i < 2 * n; ++i)
        if (!c[l[i]])
            dfs2(l[i], ++comp);

    /*for (i = 0; i < 2 * n; ++i)
        printf("%2d ", i);
    printf("\n");
    for (i = 0; i < 2 * n; ++i)
        printf("%2d ", c[i]);*/

    cc = (int**)calloc(comp, sizeof(int*));
    scc = (int*)calloc(comp, sizeof(int));
    for (i = 0; i < 2 * n; ++i) {
        cc[c[i] - 1] = (int*)realloc(cc[c[i] - 1], (scc[c[i] - 1] + 1)*sizeof(int));
        cc[c[i] - 1][scc[c[i] - 1]++] = i;
    }

    /*for (i = 0; i < comp; ++i) {
        for (j = 0; j < scc[i]; ++j)
            printf("%d ", cc[i][j]);
        printf("\n");
    }
    return 0;*/

    sat = true;
    for (i = 0; sat && i < n; ++i)
        if (c[i] == c[minus(i)])
            sat = false;

    if (!sat)
        printf("-1");
    else {
        /*for (i = 0; i < 2 * n; ++i) cval[i] = -1;
        for (i = 2 * n - 1; i >= 0; --i) {
            if (cval[c[l[i]]] == -1) {
                cval[c[l[i]]] = 0;
                cval[c[l[minus(i)]]] = 1;
            }
        }*/

        for (i = 0; i < 2 * n; ++i) cval[i] = -1;
        for (i = 2 * n - 1; i >= 0; --i) {
            if (cval[l[i]] == -1) {
                for (j = 0; j < scc[c[l[i]] - 1]; ++j)
                    cval[cc[c[l[i]] - 1][j]] = 0;
                for (j = 0; j < scc[c[minus(l[i])] - 1]; ++j)
                    cval[cc[c[minus(l[i])] - 1][j]] = 1;
            }
        }

        for (i = n; i < 2 * n; ++i)
            printf("%d ", cval[i]);
    }
    return 0;
}