Cod sursa(job #3004932)

Utilizator ptudor2Pagu Tudor ptudor2 Data 16 martie 2023 18:08:52
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#include <bits/stdc++.h>
using namespace std;

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

int n,m;
const int VAR = 100005,nmax = 100005;
vector<vector<int>> g,rev_g;
int rev(int x) { /// returns them to values you would input, 1..n
    return x - VAR;
}
int turn(int x) { /// turns values into their equivalent, high up
    return x + VAR;
}
int opp(int x) { /// makes opposites out of high up values
    return turn(-rev(x));
}


int viz1[3 * nmax],viz2[3 * nmax];
vector<int> order;
void dfs(int node) {
    viz1[node] = 1;
    for (auto k : g[node]) {
        if (viz1[k] == 0) {
            dfs(k);
        }
    }
    order.push_back(node);
}
vector<int> comp;
void dfs2(int node) {
    viz2[node] = 1;
    comp.push_back(node);
    for (auto k : rev_g[node]) {
        if (viz2[k] == 0) {
            dfs2(k);
        }
    }
}
int sol[3 * nmax],iscomp[3 * nmax];
void get_scc() {
    for (int i = 1; i <= n; i++) {
            if (viz1[turn(i)] == 0) {
                dfs(turn(i));
            }
    }

    for (int i = -n; i <= -1; i++) {
            if (viz1[turn(i)] == 0) {
                dfs(turn(i));
            }
    }
    vector<vector<int>> comps;
   // cout << "order:\n";
   // for (auto k : order) {
    //    cout << rev(k) << " ";
    //}cout << "\n";

    int id = 0;
    for (int i = (int)order.size() - 1; i >= 0; i--) {
            if (viz2[order[i]] == 0) {
                comp.clear();
                dfs2(order[i]);
                comps.push_back(comp); /// in reverse order, kids first
                for (auto k : comp) {
                    iscomp[k] = id;
                }
                id++;
            }
    }

    /*cout << "comps:\n";
    for (int i = 0; i < comps.size(); i++) {
        cout << i << ": ";
        for (auto k : comps[i]) {
            cout << rev(k) << " ";
        }
        cout << "\n";
    }*/
    for (int i = 0; i < comps.size(); i++) {
        int x = comps[i][0];

        for (auto k : comps[i]) {
            if (sol[k] == 0) {
                sol[k] = 1;
            }
        }

        for (auto k : comps[iscomp[opp(x)]]) {
            if (sol[k] == 0) {
                sol[k] = 2;
            }
        }
    }

    //for (int i = 1; i <= n; i++) {
    //    cout << i << ": sol = " << sol[turn(i)] << "\n";
   //}


   // for (int i = -n; i <= -1; i++) {
    //    cout << i << ": sol = " << sol[turn(i)] << "\n";
   // }

    for (int i = 1; i <= n; i++) {
        int x = turn(i);
        if (sol[x] == sol[opp(x)]) {
            out << "-1\n";
            return;
        }
    }

    for (int i = 1; i <= n; i++) {
        out << sol[turn(i)] - 1 << " ";
    }out << "\n";
}
int main() {
    in >> n >> m;
    g.resize(turn(n) + 1);
    rev_g.resize(turn(n) + 1);
    for (int i = 1; i <= m; i++) {
        int u,v;
        in >>u >> v;
        u = turn(u);
        v = turn(v);

        g[opp(u)].push_back(v);
        g[opp(v)].push_back(u);

      //  cout << "edge between " << rev(opp(u)) << " ^ " << rev(v) << "\n";
     //   cout << "edge between " << rev(opp(v)) << " ^ " << rev(u) << "\n";
        rev_g[v].push_back(opp(u));
        rev_g[u].push_back(opp(v));
    }//cout << "\n";

    get_scc();
}