Cod sursa(job #2553975)

Utilizator Briana_NeaguNeagu Briana Briana_Neagu Data 22 februarie 2020 14:06:12
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.47 kb
#include <bits/stdc++.h>

using namespace std;

const int nmax = 2e5 + 5;

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

int notX(int x, int n)
{
    if (x <= n)
        return x + n;
    else
        return x - n;
}

vector <int> graph[nmax];
vector <int> graphTrs[nmax];

bool vizited[nmax];
stack <int> topologicSort;

void normalDfs(int node)
{
  vizited[node] = true;
  for (auto next : graph[node])
      if (!vizited[next])
          normalDfs(next);
  topologicSort.push(node);
}

vector <int> component[nmax];
int where[nmax];

void trsDfs(int node, int cnt)
{
    vizited[node] = true;
    where[node] = cnt;
    component[cnt].push_back(node);
    for (auto next : graphTrs[node])
        if (!vizited[next])
            trsDfs(next, cnt);
}
int main()
{
    int n, m;
    f >> n >> m;
    for (int i = 1; i <= m; ++ i)
    {
        int a, b;
        f >> a >> b;
        if (a < 0)
            a = -a + n;
        if (b < 0)
            b = -b + n;
        graph[notX(a, n)].push_back(b);
        graph[notX(b, n)].push_back(a);
        graphTrs[b].push_back(notX(a, n));
        graphTrs[a].push_back(notX(b, n));
    }
    for (int i = 1; i <= n * 2; ++ i)
    {
        if (!vizited[i])
            normalDfs(i);
    }
    memset(vizited, false, nmax);
    int cnt = 0;
    while (!topologicSort.empty())
    {
        int node = topologicSort.top();
        topologicSort.pop();
        if (!vizited[node])
        {
            cnt ++;
            trsDfs(node, cnt);
        }
    }
    for (int i = 1; i <= n; ++ i)
        if (where[i] == where[i + n])
        {
            g << -1;
            return 0;
        }
    vector <int> ans(n * 2 + 2, -1);
    for (int i = 1; i <= cnt; ++ i)
    {
        bool mustBe0 = 0;
        bool mustBe1 = 0;
        for (auto node: component[i])
        {
           int neg = notX(node, n);
           if (ans[where[neg]] == 1)
               mustBe0 = 1;
           else if (ans[where[neg]] == 0)
               mustBe1 = 1;
        }
        if (mustBe0 && mustBe1)
        {
            g << -1;
            return 0;
        }
        if (mustBe1)
            ans[i] = 1;
        else
            ans[i] = 0;
    }
    memset(vizited, false, nmax);
    for (int i = 1; i <= n * 2; ++ i)
        if (ans[where[i]] == 1)
            for (auto next: graph[i])
                if (ans[where[next]] == 0)
                {
                    g << -1;
                    return 0;
                }
    for (int i = 1;  i <= n; ++ i)
        g << ans[where[i]] << '\n';

}