Cod sursa(job #1163652)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 1 aprilie 2014 15:40:19
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.18 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

vector< vector<int> > G, GT;
int V;
vector<int> Values, Sign, TopologicalOrder;
bool Compatible;

inline int Non(const int x) {
    if (x < V)
        return x + V;
    else
        return x - V;
}

void DFP(const int x) {
    ++Sign[x];
    for (vector<int>::const_iterator y = G[x].begin(); y != G[x].end(); ++y)
        if (Sign[*y] == 0)
            DFP(*y);
    TopologicalOrder.push_back(x);
}

void DFM(const int x) {
    if (Values[x] == 1) {
        Compatible = false;
        return;
    }
    Values[x] = 0;
    Values[Non(x)] = 1;
    --Sign[x];
    for (vector<int>::const_iterator y = GT[x].begin(); y != GT[x].end(); ++y)
        if (Sign[*y] == 1)
            DFM(*y);
}

void Kosaraju() {
    Sign = vector<int>(2 * V, 0);
    for (int x = 0; x < 2 * V; ++x)
        if (Sign[x] == 0)
            DFP(x);
    reverse(TopologicalOrder.begin(), TopologicalOrder.end());
    for (int i = 0; i < 2 * V; ++i) {
        int x = TopologicalOrder[i];
        if (Sign[x] == 1 && Sign[Non(x)] == 1)
            DFM(x);
    }
}

void Solve2Sat() {
    Values = vector<int>(2 * V, -1);
    Compatible = true;
    Kosaraju();
}

inline void AddEdge(const int x, const int y) {
    G[x].push_back(y);
    GT[y].push_back(x);
}

inline void AddDisjunction(const int x, const int y) {
    AddEdge(Non(x), y);
    AddEdge(Non(y), x);
}

void Read() {
    ifstream cin("2sat.in");
    int E;
    cin >> V >> E;
    G = GT = vector< vector<int> >(2 * V, vector<int>());
    for (; E > 0; --E) {
        int x, y;
        cin >> x >> y;
        if (x > 0)
            --x;
        else
            x = Non(-x - 1);
        if (y > 0)
            --y;
        else
            y = Non(-y - 1);
        AddDisjunction(x, y);
    }
    cin.close();
}

void Print() {
    ofstream cout("2sat.out");
    if (!Compatible) {
        cout << "-1\n";
    } else {
        for (int x = 0; x < V; ++x)
            cout << Values[x] << " ";
        cout << "\n";
    }
    cout.close();
}

int main() {
    Read();
    Solve2Sat();
    Print();
    return 0;
}