Cod sursa(job #1498274)

Utilizator vladiiIonescu Vlad vladii Data 8 octombrie 2015 11:28:08
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.01 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define MAXN 200100

int N, M, nrCC, hasSol = 1;
int viz[MAXN], value[MAXN];
vector<int> order;
vector<int> cc[MAXN];
vector<int> G[MAXN];
vector<int> GT[MAXN];

int Not(int x) {
    if (x > N)
        return x - N;

    return x + N;
}

void DFS(int node) {
    viz[node] = 1;

    for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); it++) {
        if (!viz[*it]) {
            DFS(*it);
        }
    }

    order.push_back(node);
}

void DFST(int node, int where) {
    viz[node] = 1;
    cc[where].push_back(node);

    for (vector<int>::iterator it = GT[node].begin(); it != GT[node].end(); it++) {
        if (!viz[*it]) {
            DFST(*it, where);
        }
    }
}

bool possible;
void can(int truth, int where) {
    for (int i = 0; i < cc[where].size(); i++) {
        int negValue = value[Not(cc[where][i])];

        if (negValue == -1) {
            value[cc[where][i]] = truth;
        } else {
            if (truth != negValue) {
                value[cc[where][i]] = truth;
            } else {
                possible = false;
                break;
            }
        }

        if (truth) {
            for (vector<int>::iterator it = G[cc[where][i]].begin(); it != G[cc[where][i]].end(); it++) {
                if (value[*it] == 0) {
                    possible = false;
                    break;
                }
            }
        }
    }
}

int main() {
    fstream f1, f2;
    f1.open("2sat.in", ios::in);
    f2.open("2sat.out", ios::out);

    f1 >> N >> M;
    int x, y;
    for (int i = 1; i <= M; i++) {
        f1 >> x >> y;
        if (x < 0)
            x = N - x;
        if (y < 0)
            y = N - y;

        G[Not(x)].push_back(y);
        G[Not(y)].push_back(x);
        GT[y].push_back(Not(x));
        GT[x].push_back(Not(y));
    }

    for (int i = 1; i <= 2*N; i++) {
        if (!viz[i]) {
            DFS(i);
        }
    }

    for (int i = 1; i <= 2*N; i++) {
        value[i] = -1;
    }

    memset(viz, 0, sizeof(viz));
    for (int i = order.size()-1; i >= 0; i--) {
        if (!viz[order[i]]) {
            nrCC ++;
            DFST(order[i], nrCC);
        }
    }

    for (int i = nrCC; i > 0; i--) {
        for (int j = 0; j < cc[i].size(); j++) {
            value[cc[i][j]] = -1;
        }
        possible = true;
        can(1, i);

        if (possible) continue;

        for (int j = 0; j < cc[i].size(); j++) {
            value[cc[i][j]] = -1;
        }
        possible = true;
        can(0, i);

        if (possible) continue;

        hasSol = 0;
        break;
    }

    if (!hasSol) {
        f2 << -1 << '\n';
    } else {
        for (int i = 1; i <= N; i++) {
            f2 << value[i] << ' ';
        } f2 << '\n';
    }

    f1.close(); f2.close();

    return 0;
}