Cod sursa(job #2942347)

Utilizator _andrei4567Stan Andrei _andrei4567 Data 19 noiembrie 2022 16:37:14
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
///x sau y
///~x->y && ~y->x
///colorare ctc
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

ifstream cin ("2sat.in");
ofstream cout ("2sat.out");

const int N = 2e5;
int ctc[N + 1], sol[N + 1];

bool viz[N + 1];

queue <int> q;

vector <int> g[N + 1], gb[N + 1], v, c[N + 1];

int n, m, x, y, k = 1;

int negare (int x)
{
    return (x > n) ? (x - n) : (x + n);
}

int valnod (int x)
{
    return (x < 0) ? n - x : x;
}

void dfsplus (int node)
{
    viz[node] = 1;
    for (auto it : g[node])
        if (!viz[it])
            dfsplus(it);
    v.push_back(node);
}

void dfsminus (int node)
{
    ctc[node] = k;
    c[k].push_back(node);
    for (auto it : gb[node])
        if (!ctc[it])
            dfsminus(it);
}

int main()
{

    for (cin >> n >> m; m && cin >> x >> y; --m)
    {
        x = valnod(x);
        y = valnod(y);
        g[negare(x)].push_back(y);
        g[negare(y)].push_back(x);
        gb[y].push_back(negare(x));
        gb[x].push_back(negare(y));
    }
    for (int i = 1; i <= (n << 1); ++i)
        if (!viz[i])
            dfsplus(i);
    reverse (v.begin(), v.end());
    for (auto it : v)
        if (!ctc[it])
            dfsminus (it), ++k;
    --k;
    for (int i = 1; i <= (n << 1); ++i)
        viz[i] = 0;
    for (int i = 1; i <= k; ++i)
    {
        for (auto it : c[i])
            viz[it] = 1;
        for (auto it : c[i])
            if (viz[it] && viz[negare(it)])
            {
                cout << "-1\n";
                return 0;
            }
        for (auto it : c[i])
            viz[it] = 0;
    }
    for (int i = 1; i <= (n << 1); ++i)
        viz[i] = 0;
    for (int i = 1; i <= (n << 1); ++i)
    {
        for (auto it : c[i])
            if (!viz[it])
                q.push(it), viz[it] = 1;
            else
                break;
        while (!q.empty())
        {
            int comp = ctc[negare(q.front())];
            int val = sol[q.front()];
            q.pop();
            for (auto it : c[comp])
                if (!viz[it])
                    viz[it] = 1, sol[it] = val ^ 1, q.push(it);
                else
                    break;
        }
    }
    for (int i = 1; i <= n; ++i)
        cout << sol[i] << ' ';
    return 0;
}