Cod sursa(job #2294661)

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

using namespace std;
            
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) {}
    
    void Implies(int a, int b) {
        graph[a].push_back(b);
        graph[b ^ 1].push_back(a ^ 1);
    };
    void Either(int a, int b) { Implies(a ^ 1, b); }

    void dfs1(int node) {
        if (vis[node]) return; 
        vis[node] = 1;
        for (auto vec : graph[node]) 
            dfs1(vec);
        order.push_back(node);
    }
    void dfs2(int node) {
        if (sol[node / 2] == node % 2) throw 5;
        sol[node / 2] = !(node % 2);
        if (!vis[node]) return;
        vis[node] = vis[node ^ 1] = 0;
        for (auto vec : graph[node ^ 1]) 
            dfs2(vec ^ 1); 
    }

    vector<int> Solve() {
        for (int i = 0; i < 2 * n; ++i)
            dfs1(i);
        for (int i = 2 * n - 1; i >= 0; --i)
            if (vis[order[i]])
                dfs2(order[i]);
        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 2 * (-x - 1);
        return 2 * (x - 1) + 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;
}