Cod sursa(job #2931901)

Utilizator Cezar211Popoveniuc Cezar Cezar211 Data 1 noiembrie 2022 10:37:04
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>

#define NMAX 100005
using namespace std;

void fast() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}

int N, M;
vector<int> v[2 * NMAX], inv[2 * NMAX];

int transform(int x) {
    if (x < 0)
        return N - x;
    return x;
}

int neg(int x) {
    if (x > N)
        return x - N;
    return x + N;
}

// negated will be N + node
void getInverseGraph() {
    for (int i = 1; i <= 2 * N; i++) {
        for (auto it: v[i])
            inv[it].push_back(i);
    }
}

void read() {
    ifstream fin("2sat.in");
    fin >> N >> M;
    for (int i = 0; i < M; i++) {
        int x, y;
        fin >> x >> y;
        x = transform(x), y = transform(y);
        v[neg(x)].push_back(y);
        v[neg(y)].push_back(x);
    }
    getInverseGraph();
}

vector<int> order;
bool viz[2 * NMAX];
int cc[2 * NMAX];

void dfs1Kosaraju(int node) {
    viz[node] = true;
    for (auto it: v[node])
        if (!viz[it])
            dfs1Kosaraju(it);
    order.push_back(node);
}

void dfs2Kosaraju(int node, int crtCC) {
    cc[node] = crtCC;
    for (auto it: inv[node])
        if (!cc[it])
            dfs2Kosaraju(it, crtCC);
}

bool solve2SAT(bool assignment[]) {
    for (int i = 1; i <= 2 * N; i++)
        if (!viz[i])
            dfs1Kosaraju(i);
    int crtCC = 0;
    for (auto node = order.rbegin(); node != order.rend(); node++)
        if (!cc[*node]) {
            dfs2Kosaraju(*node, ++crtCC);
            // kosaraju gets connected components already in topological order
        }
    for (int i = 1; i <= N; i++)
        if (cc[i] == cc[i + N])
            return false;
    memset(assignment, false, sizeof(bool) * 2 * NMAX);
    for (int i = 1; i <= N; i++) {
        assignment[i] = cc[i] > cc[N + i];
    }
    return true;
}

int main() {
    fast();
    read();
    ofstream fout("2sat.out");
    bool assignment[2 * NMAX];
    if (solve2SAT(assignment)) {
        for (int i = 1; i <= N; i++)
            fout << assignment[i] << ' ';
    } else fout << -1 << '\n';
}