Cod sursa(job #3345609)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 10 martie 2026 12:41:18
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <bits/stdc++.h>

class sat {
    int n;
    std::vector<std::vector<int>> adj, adj_r;
    int nr_comps;
    std::vector<int> comp_of;

    void dfs(int nod, std::vector<bool> &viz, std::vector<int> &ord, std::vector<std::vector<int>> &adj)
    {
        if (viz[nod]) {
            return;
        }
        viz[nod] = true;
        for (auto &c : adj[nod]) {
            dfs(c, viz, ord, adj);
        }
        ord.push_back(nod);
    }

public:
    sat(int _n)
    {
        n = 2 * _n;
        nr_comps = 0;
        adj = adj_r = std::vector<std::vector<int>> (n);
        comp_of.assign(n, -1);
    }

    void add_edge(int x, bool sign_x, int y, bool sign_y)
    {
        x = (x << 1) | sign_x;
        y = (y << 1) | sign_y;
        x ^= 1;
        adj[x].push_back(y);
        adj_r[y].push_back(x);
        x ^= 1;
        y ^= 1;
        adj[y].push_back(x);
        adj_r[x].push_back(y);
    }

    void ctc()
    {
        std::vector<bool> viz(n, false);
        std::vector<int> ord;
        for (int i = 0; i < n; i++) {
            dfs(i, viz, ord, adj);
        }
        std::reverse(ord.begin(), ord.end());
        viz = std::vector<bool> (n, false);
        for (auto &c : ord) {
            if (!viz[c]) {
                std::vector<int> v;
                dfs(c, viz, v, adj_r);
                for (auto &c : v) {
                    comp_of[c] = nr_comps;
                }
                nr_comps++;
            }
        }
    }

    bool check_sol_exists()
    {
        for (int i = 0; i < n; i += 2) {
            if (comp_of[i] == comp_of[i | 1]) {
                return false;
            }
        }
        return true;
    }
    bool get_sign (int idx)
    {
        return comp_of[idx << 1] < comp_of[idx << 1 | 1];
    }
};

int main()
{
    freopen("2sat.in", "r" , stdin);
    freopen("2sat.out", "w", stdout);
    int n, m;
    std::cin >> n >> m;
    sat v(n);
    for (int i = 0; i < m; i++) {
        int x, y;
        std::cin >> x >> y;
        bool sign_x = x > 0;
        bool sign_y = y > 0;
        x = abs(x) - 1;
        y = abs(y) - 1;
        v.add_edge(x, sign_x, y, sign_y);
    }
    v.ctc();
    if (!v.check_sol_exists()) {
        std::cout << -1;
    } else {
        for (int i = 0; i < n; i++) {
            std::cout << v.get_sign(i) << ' ';
        }
    }
}