Cod sursa(job #2953320)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 10 decembrie 2022 23:10:09
Problema 2SAT Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#include <fstream>
#include <vector>
#include <algorithm> ///Pentru reverse pe vector (nu l-am mai folosit).

using namespace std;

const int NMAX = 100000;

int n, m;

vector<int> graf[1 + 2 * NMAX]; ///2 * NMAX pentru a cuprinde si negatiile (intre n + 1 si 2n inclusiv sunt negatiile)
vector<int> grafInv[1 + 2 * NMAX];

vector<int> lista;

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

bool vizitat[1 + 2 * NMAX];
int compID[1 + 2 * NMAX];

void dfs(int nod)
{
    vizitat[nod] = true;

    for (int i = 0; i < graf[nod].size(); i++)
        if (!vizitat[graf[nod][i]])
            dfs(graf[nod][i]);

    lista.push_back(nod);
}

int nrCompTareConex;
void dfsInv(int nod)
{
    compID[nod] = nrCompTareConex;

    for (int i = 0; i < grafInv[nod].size(); i++)
        if (compID[grafInv[nod][i]] == 0)
            dfsInv(grafInv[nod][i]);
}

int main()
{
    ios_base::sync_with_stdio(false);

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

    in >> n >> m;

    for (int j = 1; j <= m; j++)
    {
        int a, b;
        in >> a >> b;

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

        graf[non(a)].emplace_back(b);
        graf[non(b)].emplace_back(a);

        grafInv[a].emplace_back(non(b));
        grafInv[b].emplace_back(non(a));
    }

    for (int i = 1; i <= 2 * n; i++)
        if (!vizitat[i])
            dfs(i);

    for (int i = 2 * n; i >= 1; i--) ///Important, luam invers elementele din lista. Componentele tare conexe vor fi in ordine topologica.
    {
        if (compID[lista[i]] == 0)
        {
            nrCompTareConex++;
            dfsInv(lista[i]);
        }
    }

    bool ok = true;

    for (int i = 1; i <= n && ok; i++)
        if (compID[i] == compID[i + n])
            ok = false;

    if (ok)
    {
        for (int i = 1; i <= n; i++)
        {
            if (compID[i] < compID[i + n])
                out << 0 << ' ';
            else
                out << 1 << ' ';
        }
        out << '\n';
    }
    else
    {
        out << -1 << '\n';
    }

    in.close();
    out.close();

    return 0;
}