Cod sursa(job #2959253)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 30 decembrie 2022 12:55:25
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct SAT2
{
    int n;
    int spec;
    int cur;
    vector<bool> vis;
    vector<vector<int>> g;
    vector<vector<int>> ig;
    vector<int> ord;
    vector<int> comp;

    SAT2(int n, int spec) :
        n(n),
        spec(spec),
        comp(2 * n + 1 + spec, 0),
        vis(2 * n + 1 + spec, 0),
        g(2 * n + 1 + spec),
        ig(2 * n + 1 + spec),
        cur(0)
    {
#ifdef ONPC
        cout << "salut SAT2!\n";
#endif // ONPC
    }

    void dfs(int a)
    {
        if (vis[a])
        {
            return;
        }
        vis[a] = 1;
        for (auto& b : g[a])
        {
            dfs(b);
        }
        ord.push_back(a);
    }

    void invdfs(int a)
    {
        if (vis[a])
        {
            return;
        }
        comp[a] = cur;
        vis[a] = 1;
        for (auto& b : ig[a])
        {
            invdfs(b);
        }
    }

    void addEdge(int a, int b)
    {
        assert(1 <= a && a <= 2 * n + spec);
        assert(1 <= b & b <= 2 * n + spec);
        g[a].push_back(b);
        ig[b].push_back(a);
    }
    int inv(int x)
    {
        assert(1 <= x && x <= 2 * n);
        if (x <= n)
        {
            return x + n;
        }
        else
        {
            return x - n;
        }
    }
    bool solve()
    {
        for (int i = 1; i <= 2 * n + spec; i++)
        {
            dfs(i);
        }
        reverse(ord.begin(), ord.end());
        for (int i = 1; i <= 2 * n + spec; i++)
        {
            vis[i] = 0;
        }
        for (auto& i : ord)
        {
            if (vis[i])
            {
                continue;
            }
            cur++;
            invdfs(i);
        }
        for (int i = 1; i <= n; i++)
        {
            if (comp[i] == comp[i + n])
            {
                return 0;
            }
        }
        return 1;
    }
};

signed main()
{
#ifdef ONPC
    freopen("input.txt", "r", stdin);
#endif // ONPC

#ifndef ONPC
    freopen ("2sat.in", "r", stdin);
    freopen ("2sat.out", "w", stdout);
#endif // ONPC



    int n, m;
    scanf("%d %d", &n, &m);


    SAT2 sat(n, 0);

    for (int i = 1; i <= m; i++)
    {
        int a, b;
        scanf("%d %d", &a, &b);

        if (a < 0) a = n - a;
        if (b < 0) b = n - b;

        assert(1 <= a && a <= 2 * n);
        assert(1 <= b && b <= 2 * n);

        sat.addEdge(sat.inv(a), b);
        sat.addEdge(sat.inv(b), a);

    }

    bool ok = sat.solve();
    if (!ok)
    {
        cout << "-1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++)
    {
        cout << (sat.comp[i] > sat.comp[i + n]) << " ";
    }
    cout << "\n";
    return 0;
}
/**

**/