Cod sursa(job #2294644)

Utilizator retrogradLucian Bicsi retrograd Data 2 decembrie 2018 17:20:31
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <bits/stdc++.h>

using namespace std;
            
int put(int x) {
    if (x < 0) return -((~x) + 1);
    return x + 1;
};

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

    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 dfs1(int x) {
        int node = get_node(x);
        if (vis[node]) return; 
        vis[node] = 1;
        for (auto vec : graph[node]) dfs1(vec);
        order.push_back(x);
    }
    void dfs2(int x) {
        if (get_sol(x) == 1) throw 5;
        set_sol(~x);
        int node = get_node(~x);
        if (!vis[node]) return;
        vis[node] = vis[node ^ 1] = 0;
        for (auto vec : graph[node]) dfs2(~vec); 
    }

    vector<int> Solve() {
        for (int i = 0; i < n; ++i)
            for (auto x : {i, ~i})
                dfs1(x);
        reverse(order.begin(), order.end());
        for (auto x : order)
            if (vis[get_node(x)])
                dfs2(x);

        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);
    }
    try {
        for (auto x : sat.Solve()) 
            cout << x << " ";
    } catch (int) { cout << -1 << endl; }
    
    return 0;
}