Cod sursa(job #2294594)

Utilizator fminostress2018Fmi no stress 2018 fminostress2018 Data 2 decembrie 2018 16:31:57
Problema 2SAT Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>

using namespace std;

struct TwoSat {
    int n;
    vector<vector<int>> graph;
    vector<int> sol, vis;

    TwoSat(int n) : n(n), graph(2 * n), sol(n, -1), vis(2 * n, 0) {}
    
    int get_node(int x) { return x < 0 ? (2 * (~x) + 1) : 2 * x; }
    int get_sol(int x) {
        int idx = x < 0 ? (~x) : x;
        if (sol[idx] == -1) return -1;
        return sol[idx] ^ (x < 0);
    }
    void set_sol(int x) { x < 0 ? sol[~x] = 0 : sol[x] = 1; }
    
    void Implies(int a, int b) {
        graph[get_node(a)].push_back(b);
        graph[get_node(~b)].push_back(~a);
    };
    void Either(int a, int b) { Implies(~a, b); }

    void dfs(int x) {
        int node = get_node(x);
        if (vis[node]) return; 
        vis[node] = 1;
        for (auto vec : graph[node]) dfs(vec);
        if (get_sol(x) == -1) set_sol(x);
    }

    vector<int> Solve() {
        for (int i = 0; i < n; ++i)
            for (auto x : {i, ~i})
                dfs(x);
        for (int i = 0; i < n; ++i) 
            for (auto x : {i, ~i})
                for (auto vec : graph[get_node(x)])
                    if (get_sol(x) && !get_sol(vec))
                        return {-1};
        return sol;
    };
};

int main() {
    ifstream cin("2sat.in");
    ofstream cout("2sat.out");

    int n, m; cin >> n >> m;
    TwoSat sat(n);
    auto read = [&]() {
        int x; cin >> x;
        if (x < 0) return ~(-x - 1);
        return x - 1;
    };
    for (int i = 0; i < m; ++i) {
        int a = read(), b = read();
        sat.Either(a, b);
    }
    for (auto x : sat.Solve()) 
        cout << x << " ";
    
    return 0;
}