Cod sursa(job #3198689)

Utilizator AleXutzZuDavid Alex Robert AleXutzZu Data 30 ianuarie 2024 09:29:09
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <fstream>
#include <vector>
#include <stack>

struct Graph {
private:
    std::vector<std::vector<int>> adj;
    std::vector<std::vector<int>> transpose;
    int size;
    std::vector<int> comp;
    std::stack<int> stack;

    void dfs(int node) {
        if (comp[node] != -1) return;
        comp[node] = 1;

        for (const auto &x: adj[node]) dfs(x);
        stack.push(node);
    }

    void assign(int node, int component) {
        if (comp[node] != -1) return;
        comp[node] = component;
        for (const auto &x: transpose[node]) assign(x, component);
    }

public:
    explicit Graph(int size) : size(size) {
        adj.resize(size + 1);
        transpose.resize(size + 1);
        comp.resize(size + 1, -1);
    }

    void add_edge(int x, int y) {
        adj[x].push_back(y);
        transpose[y].push_back(x);
    }

    std::vector<int> assign_components() {

        for (int i = 1; i <= size; ++i) dfs(i);
        comp.assign(size + 1, -1);
        int cnt = 0;

        while (!stack.empty()) {
            if (comp[stack.top()] == -1) cnt++;
            assign(stack.top(), cnt);
            stack.pop();
        }

        return comp;
    }
};

int main() {
    std::ifstream input("2sat.in");
    std::ofstream output("2sat.out");

    int n, m;
    input >> n >> m;

    Graph graph(2 * n);

    auto get_node = [&n](int x) {
        if (x < 0) return n - x;
        return x;
    };

    for (int i = 0; i < m; ++i) {
        int x, y;
        input >> x >> y;
        graph.add_edge(get_node(-x), get_node(y));
        graph.add_edge(get_node(-y), get_node(x));
    }

    auto comp = graph.assign_components();

    std::vector<bool> assignment(n + 1);
    bool doable = true;
    for (int i = 1; i <= n; ++i) {
        if (comp[i] == comp[i + n]) doable = false;
        if (comp[i] < comp[i + n]) assignment[i] = false;
        else assignment[i] = true;
    }

    if (!doable) output << -1;
    else {
        for (int i = 1; i <= n; ++i) output << assignment[i] << " ";
    }
    return 0;
}