Cod sursa(job #2910636)

Utilizator avtobusAvtobus avtobus Data 23 iunie 2022 10:33:26
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.17 kb
#include <algorithm>
#include <stdio.h>
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

int main(void) {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  freopen("2sat.in", "r", stdin);
  freopen("2sat.out", "w", stdout);

  int N, M;
  cin >> N >> M;
  vector<vi> G(2*N), revG(2*N);
  for(int i = 0; i < M; i++) {
    int a,b;
    cin >> a >> b;
    int sa = a < 0, sb = b < 0;
    a = sa ? -a : a;
    b = sb ? -b : b;
    --a, --b;
    int noda = (2*a)^sa, nodb = (2*b)^sb;
    // not(a) -> b
    G[noda^1].push_back(nodb);
    revG[nodb].push_back(noda^1);
    // not(b) -> a
    G[nodb^1].push_back(noda);
    revG[noda].push_back(nodb^1);
  }

  vi topo;
  vector<bool> vis(2*N, 0);
  auto dfs1 = [&](auto self, int nod)->void{
    vis[nod] = 1;
    for(auto nbr: G[nod]) if (!vis[nbr]) {
      self(self, nbr);
    }
    topo.push_back(nod);
  };
  for(int i = 0; i < 2*N; i++) if (!vis[i]) {
    dfs1(dfs1, i);
  }

  reverse(topo.begin(), topo.end());
  vector<bool> assigned(N, 0), sol(N, 0);
  fill(vis.begin(), vis.end(), 0);
  vector<vi> components;
  auto dfs2 = [&](auto self, int nod)->void{
    vis[nod] = 1;
    auto &comp = components.back();
    comp.push_back(nod);
    for(auto nbr: revG[nod]) if(!vis[nbr]) {
      self(self, nbr);
    }
  };
  for(auto nod: topo) if (!vis[nod]) {
    components.emplace_back();
    dfs2(dfs2, nod);
  }
  reverse(components.begin(), components.end());
  for(const auto &comp: components) {
    int cur = -1;

    for(auto x: comp) if (assigned[x/2]) {
      int val = sol[x/2];
      val = x&1 ? !val : val;
      if (cur == -1) {
        cur = val;
      } else if (cur != val) {
        cout << "-1\n";
        return 0;
      }
    }
    if (cur == -1) cur = 1;
    for(auto x: comp) {
      if (!assigned[x/2]) {
        assigned[x/2] = 1;
        sol[x/2] = x&1 ? !cur : cur;
      } else {
        int val = sol[x/2];
        val = x&1 ? !val : val;
        if (cur != val) {
          cout << "-1\n";
          return 0;
        }
      }
    }
  }
  for(auto x: sol) { cout << x << ' '; } cout << "\n";

  return 0;
}