Cod sursa(job #2845261)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 7 februarie 2022 17:52:06
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>

using namespace std;
class SAT2 {
    int n;
    vector <bool> exp;
    vector <vector <int>> g, tg;
    int getnode(int expr) { if(expr < 0) return (~expr) << 1 | 1; return expr - 1 << 1; }
    int scc_count;
    vector <int> group, traversal;
    vector <bool> vis;
    void dfs(int u, bool transpose = false) {
        if(!transpose) vis[u] = true;
        else group[u] = scc_count;
        for(int v : (!transpose ? g[u] : tg[u]))
            if((!transpose ? !vis[v] : !group[v]))
                dfs(v, transpose);
        if(!transpose) traversal.push_back(u);
    }
public:
    SAT2(int _n) : n(_n), exp(_n, false), g(2 * _n), tg(2 * _n), group(2 * _n), traversal(0), vis(2 * _n, false) {}
    void add_expr(int x, int y) {
        int u = getnode(x), v = getnode(y);
        g[u ^ 1].push_back(v);
        g[v ^ 1].push_back(u);
        tg[u].push_back(v ^ 1);
        tg[v].push_back(u ^ 1);
    }
    inline bool solve() {
        for(int i = 0; i < 2 * n; i++) if(!vis[i])
            dfs(i);
        reverse(traversal.begin(), traversal.end());
        for(int node : traversal) if(!group[node])
            dfs(node, ++scc_count);
        for(int i = 0; i < 2 * n; i += 2) {
            if(group[i] == group[i ^ 1])
                return false;
            exp[i >> 1] = group[i] > group[i ^ 1];
        }
        return true;
    }
    vector <bool> get_solution() {
        return exp;
    }
};

int main()
{
    ifstream cin("2sat.in");
    ofstream cout("2sat.out");
    int n, m, x, y;
    cin >> n >> m;
    SAT2 S(n);
    for(int i = 1; i <= m; i++)
        cin >> x >> y,
        S.add_expr(x, y);
    if(!S.solve()) cout << "-1";
    else {
        vector <bool> sol = S.get_solution();
        for(bool x : sol)
            cout << x << " ";
    }
    return 0;
}