Cod sursa(job #2957718)

Utilizator lucaperjuLuca Perju Verzotti lucaperju Data 23 decembrie 2022 13:10:53
Problema 2SAT Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.53 kb
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <cstring>
#include <chrono>
#include <cassert>
#include <bitset>
#include <stack>
#include <queue>
#include <iomanip>
#include <random>
#include <string>
#include <complex>
#include <algorithm>
#include <numeric>
//#include <ext/pb_ds/assoc_container.hpp>

#ifdef _MSC_VER
#  include <intrin.h>
#  define __builtin_popcount __popcnt
#  define __builtin_popcountll __popcnt64
#endif

#pragma warning(disable : 4996)

#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define x first
#define y second
#define ld long double
#define ll long long
#define ull unsigned long long
#define us unsigned short
#define lsb(x) ((x) & (-(x)))
#define pii pair <int, int>
#define pll pair <ll, ll>

using namespace std;
//using namespace __gnu_pbds;

mt19937_64 gen(time(0));
uniform_int_distribution <ull> rng;

struct Sat {
    int n;

    vector <vector <int>> g, gr;
    vector <int> ind, low;
    vector <int> st, comp;

    int timer, comp_ind;

    void init(int _n) {
        n = _n;
        timer = comp_ind = 0;
        g.resize(2 * n + 1), gr.resize(2 * n + 1);
        ind.resize(2 * n + 1), low.resize(2 * n + 1);
        comp.resize(2 * n + 1);
    }

    int neg(int x) {
        if (x <= n)
            return n + x;
        return x - n;
    }

    void add_edge(int x, int y) {
        g[neg(x)].push_back(y);
        g[neg(y)].push_back(x);
        //gr[y].push_back(neg(x));
        //gr[x].push_back(neg(y));
    }

    void dfs(int node) {
        ind[node] = low[node] = ++timer;
        st.push_back(node);

        for (auto& son : g[node]) {
            if (!ind[son]) {
                dfs(son);
                low[node] = min(low[node], low[son]);
            }
            else {
                low[node] = min(low[node], ind[son]);
            }
        }

        if (low[node] == ind[node]) {
            comp_ind++;
            while (st.back() != node) {
                int c_node = st.back();
                comp[c_node] = comp_ind;
                st.pop_back();
            }
            comp[st.back()] = comp_ind;
            st.pop_back();
        }
    }

    vector <bool> solve() {
        for (int i = 1; i <= 2 * n; i++) {
            if (!ind[i]) {
                st.clear();
                dfs(i);
            }
        }

        vector <bool> val(n + 1);
        bool can = 1;
        for (int i = 1; i <= n; i++) {
            if (comp[i])
                can &= (comp[i] != comp[neg(i)]);
            val[i] = comp[i] > comp[neg(i)];
        }

        val[0] = can;

        return val;
    }
} sat;

void solve() {
    int n, m, x, y;
    cin >> n >> m;

    sat.init(2 * n);
    for (; m; m--) {
        cin >> x >> y;
        if (x < 0)
            x = sat.neg(-x);
        if (y < 0)
            y = sat.neg(-y);
        sat.add_edge(x, y);
    }

    vector <bool> val = sat.solve();

    if (!val[0]) {
        cout << "-1\n";
        return;
    }

    for (int i = 1; i <= n; i++)
        cout << val[i] << " ";
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    srand(time(0));

#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif

    int T = 1;

    //cin >> T;

    for (int t = 1; t <= T; t++) {
        solve();
    }

    return 0;
}