Cod sursa(job #2972845)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 30 ianuarie 2023 15:18:15
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.12 kb
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX_N 200005
using namespace std;
ifstream cin("2sat.in");
ofstream cout("2sat.out");

int variables, expressions;

vector <int> var_adj[MAX_N], var_adj_t[MAX_N], vtc(MAX_N), value(MAX_N, -1), scc_in_deg(MAX_N, 0);

vector < vector <int> > sccs;


inline int abs(const int x) {
    return (x < 0) ? -x : +x;
}

inline int idx(const int x) {
    return (x < 0) ? abs(x) + variables : x;
}

inline int non(const int x) {
    return (x > variables) ? x - variables : x + variables;
}

void DFP(int n, vector <int>& used, vector <int>& discover) {
    vector <int>::iterator it;
    used[n] = 1;
    for (it = var_adj[n].begin(); it != var_adj[n].end(); ++ it)
        if (!used[*it])
            DFP(*it, used, discover);
    discover.push_back(n);
}

void DFM(int n, vector <int>& used, vector <int>& scc) {
    vector <int>::iterator it;
    used[n] = 1;
    scc.push_back(n);
    for (it = var_adj_t[n].begin(); it != var_adj_t[n].end(); ++ it)
        if (!used[*it])
            DFM(*it, used, scc);
}

void compute_sccs(void) {
    vector <int> used(MAX_N), discover, scc;

    used.assign(used.size(), 0);
    for (int i = 1; i <= variables * 2; ++ i)
        if (!used[i])
            DFP(i, used, discover);
    used.assign(used.size(), 0);
    vector <int>::reverse_iterator it;
    for (it = discover.rbegin(); it != discover.rend(); ++ it) {
        if (!used[*it]) {
            scc.clear();
            DFM(*it, used, scc);
            for (vector <int>::iterator it2 = scc.begin(); it2 != scc.end(); ++ it2)
                vtc[*it2] = sccs.size();
            sccs.push_back(scc);
        }
    }
}
int main()
{
    cin>>variables>>expressions;

    for(int i=0;i<expressions;++i)
    {
        int x,y;
        cin>>x>>y;
        var_adj[non(idx(x))].push_back(idx(y));
        var_adj_t[idx(y)].push_back(non(idx(x)));
        var_adj[non(idx(y))].push_back(idx(x));
        var_adj_t[idx(x)].push_back(non(idx(y)));
    }

    compute_sccs();

    bool impossible = false;
    for(int i=1;i<=variables;++i)
        if(vtc[i] == vtc[i+variables])
            impossible = true;
    if(impossible)
    {
        cout<<"-1";
        return 0;
    }

    for(int x = 1; x <= 2*variables; ++x)
        for(auto i : var_adj[x])
            if(vtc[x] != vtc[i])
                scc_in_deg[vtc[i]]++;

    queue<int> Q;
    for(int idx=0; idx < sccs.size(); ++idx)
        if(scc_in_deg[idx] == 0)
            Q.push(idx);

    while(!Q.empty())
    {
        int idx = Q.front();
        Q.pop();

        for(auto i : sccs[idx])
        {
            int x = (i > variables) ? i - variables : i;
            if(value[x] == -1)
                value[x] = (i <= variables) ? 0 : 1;
        }

        for(auto i : sccs[idx])
            for(auto j : var_adj[i])
                if(vtc[i] != vtc[j])
                    if( -- scc_in_deg[vtc[j]] == 0)
                        Q.push(vtc[j]);
    }

    for(int i=1;i<=variables;++i)
        cout<<value[i]<<' ';
    return 0;
}