Cod sursa(job #1451163)

Utilizator klamathixMihai Calancea klamathix Data 16 iunie 2015 11:55:43
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.71 kb
#include <bits/stdc++.h>
using namespace std;
#define VI vector<int>

class SATSolver {
    
    static int norm(int n, int x) {
        if(x < 0) 
            return -x + n;
        return x;
    }

    static void dfs(int node, vector<VI> &G, VI &seen, VI &st) {
        seen[node] = 1;
        for(auto temp : G[node])
            if(!seen[temp])
                dfs(temp, G, seen, st);
        st.push_back(node);
    }

    static void dfs2(int node, vector<VI> &G, VI &comp, int c, VI &order) {
        comp[node] = c;
        order.push_back(node);
        for(auto temp : G[node])
            if(comp[temp] < 0)
                dfs2(temp, G, comp, c, order);
    }

    static int other(int n, int x) {
        if(x > n)
            return x - n;
        return x + n;
    }

    public:
    static vector<int> solve(int n, vector<pair<int, int>> C) {
        int m = C.size();
        vector<VI> G(2 * n + 2, VI()), T(2 * n + 2, VI());

        for(int i = 0; i < m; ++i) {
            G[norm(n, -C[i].first)].push_back(norm(n, C[i].second));
            G[norm(n, -C[i].second)].push_back(norm(n, C[i].first));
        }

        for(int i = 1; i <= 2 * n; ++i)
            for(auto temp : G[i])
                T[temp].push_back(i);

        vector<int> st, seen(2 * n + 1, 0);

        for(int i = 1; i <= 2 * n; ++i)
            if(!seen[i]) 
                dfs(i, T, seen, st);
        
        reverse(st.begin(), st.end());
        vector<int> comp(2 * n + 1, -1);
        int SCC = 0;
        
        vector<int> order;
        for(int i = 1; i <= 2 * n; ++i)
            if(comp[st[i - 1]] == -1) {
                ++SCC;
                dfs2(st[i - 1], G, comp, SCC, order);
            }
        
        for(int i = 1; i <= n; ++i)
            if(comp[i] == comp[i + n])
                return VI();

        vector<int> value(2 * n + 1, -1);
        vector<VI> components(SCC + 1, VI());

        for(int i = 1; i <= 2 * n; ++i) 
            components[comp[i]].push_back(i);

        for(int i = 0; i < 2 * n; ++i) {
            int node = order[i];
            if(value[node] >= 0)
                continue;
            for(auto temp : components[comp[node]]) {
                value[temp] = 1;
                value[other(n, temp)] = 0;
            }
        }

        return value;
    }

};

int main() {
    
    ifstream cin("2sat.in");
    ofstream cout("2sat.out");
    
    ios_base :: sync_with_stdio(false);

    int n, m; cin >> n >> m;
    vector<pair<int, int>> c(m);

    for(int i = 0; i < m; ++i) 
        cin >> c[i].first >> c[i].second;
    
    vector<int> sol = SATSolver :: solve(n, c);
    if(sol.empty()) 
        cout << -1 << "\n";
    else {
        for(int i = 1; i <= n; ++i)
            cout << sol[i] << " ";
    }
}