Cod sursa(job #3233285)

Utilizator MirceaDonciuLicentaLicenta Mircea Donciu MirceaDonciuLicenta Data 2 iunie 2024 21:25:30
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.33 kb
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include <fstream>

using namespace std;

class TwoSat {
public:
    TwoSat(int n) : n(n), adj(2 * n), adjRev(2 * n), visited(2 * n, false), comp(2 * n, -1), assignment(n, -1) {}

    void addClause(int u, int v) {
        adj[negate(u)].push_back(v);
        adj[negate(v)].push_back(u);
        adjRev[v].push_back(negate(u));
        adjRev[u].push_back(negate(v));
    }

    bool solve() {
        for (int i = 0; i < 2 * n; ++i) {
            if (!visited[i]) dfs1(i);
        }
        fill(visited.begin(), visited.end(), false);
        int compIdx = 0;
        while (!order.empty()) {
            int v = order.top();
            order.pop();
            if (!visited[v]) {
                dfs2(v, compIdx++);
            }
        }
        for (int i = 0; i < n; ++i) {
            if (comp[i] == comp[negate(i)]) return false;
            assignment[i] = (comp[i] > comp[negate(i)]);
        }
        return true;
    }

    vector<int> getAssignment() {
        return assignment;
    }

private:
    int n;
    vector<vector<int>> adj, adjRev;
    vector<bool> visited;
    vector<int> comp, assignment;
    stack<int> order;

    int negate(int x) {
        return x >= n ? x - n : x + n;
    }

    void dfs1(int v) {
        visited[v] = true;
        for (int u : adj[v]) {
            if (!visited[u]) dfs1(u);
        }
        order.push(v);
    }

    void dfs2(int v, int compIdx) {
        visited[v] = true;
        comp[v] = compIdx;
        for (int u : adjRev[v]) {
            if (!visited[u]) dfs2(u, compIdx);
        }
    }
};

int main() {
    ifstream infile("2sat.in");
    ofstream outfile("2sat.out");

    int N, M;
    infile >> N >> M;

    TwoSat solver(N);

    for (int i = 0; i < M; ++i) {
        int u, v;
        infile >> u >> v;
        u = (u > 0 ? u - 1 : N - u - 1);
        v = (v > 0 ? v - 1 : N - v - 1);
        solver.addClause(u, v);
    }

    if (solver.solve()) {
        vector<int> result = solver.getAssignment();
        for (int i = 0; i < N; ++i) {
            outfile << result[i] << " ";
        }
        outfile << endl;
    } else {
        outfile << -1 << endl;
    }

    infile.close();
    outfile.close();

    return 0;
}