Cod sursa(job #3216653)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 18 martie 2024 22:37:28
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.43 kb
#include <vector>
#include <fstream>
#include <functional>

using namespace std;
template<typename T>
struct BiVec {
    vector<T> v;
    BiVec(int n, T x = {}) : v(2 * n, x) {}
    T& operator[](int i) {
        return v[2 * max(i, ~i) + (i < 0)];
    }
    void resize(int n) {
        v.resize(2 * n);
    }
};

struct TwoSat {
    int n;
    BiVec<vector<int>> graph;
    TwoSat(int n) : n(n), graph(n) {}
    void Implies(int a, int b) {
        graph[a].push_back(b);
        graph[~b].push_back(~a);
    }
    void Either(int a, int b) {
        Implies(~a, b);
    }
    void SetValue(int x) {
        Either(x, x);
    }
    int AddVar() {
        graph.resize(++n);
        return n - 1;
    }
    void AtMostOne(const vector<int>& vals) {
        if (vals.size() <= 1) return;
        int cur = ~vals[0];
        for (int i = 2; i < (int)vals.size(); ++i) {
            int nxt = AddVar();
            Either(cur, ~vals[i]);
            Either(cur, nxt);
            Either(~vals[i], nxt);
            cur = ~nxt;
        }
        Either(cur, ~vals[1]);
    }
    vector<int> Solve() {
        BiVec<int> vis(n);
        vector<int> stk;
        int cc = 0;
        function<void(int)> dfs1 = [&](int node) {
            if (vis[node]) return;
            vis[node] = -1;
            for (auto vec : graph[node])
                dfs1(vec);
            stk.push_back(node);
        };
        function<void(int)> dfs2 = [&](int node) {
            if (vis[node] != -1) return;
            vis[node] = cc;
            for (auto vec : graph[~node])
                dfs2(~vec);
        };
        for (int i = 0; i < n; ++i) dfs1(i), dfs1(~i);
        for (int i = 2 * n - 1; i >= 0; --i) ++cc, dfs2(stk[i]);
        vector<int> ans(n);
        for (int i = 0; i < n; ++i) {
            if (vis[i] == vis[~i]) return {};
            ans[i] = vis[i] > vis[~i];
        }
        return ans;
    }
};

int read(istream& cin) {
    int x;
    cin >> x;
    if (x > 0) --x;
    return x;
}

int main() {
    ifstream cin("2sat.in");
    ofstream cout("2sat.out");
    int n, m;
    cin >> n >> m;
    TwoSat sat(n);
    for (int i = 0; i < m; ++i) {
        sat.Either(read(cin), read(cin));
    }
    auto sol = sat.Solve();
    if (sol.empty()) cout << "-1\n";
    else {
        for (int i = 0; i < n; ++i)
            cout << sol[i] << " ";
        cout << endl;
    }
    return 0;
}