Cod sursa(job #2095720)

Utilizator Alex18maiAlex Enache Alex18mai Data 28 decembrie 2017 08:35:21
Problema 2SAT Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.98 kb
#include <fstream>
#include <vector>
#include <map>
#include <queue>

using namespace std;

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

vector < vector <int> > gr(200100);
vector < vector <int> > inv(200100);

vector < bool > used(200100);
vector < bool > USED(200100);

map < int , bool > M;

vector < int > now;
vector < int > NOW;

vector < vector < int > > comp(200100);
vector < int > COMP (200100);
int cont = 0;
vector < vector <int> > GR(200100);
vector < int > enter (200100);

queue < int > Q;
vector < int > ord_top;

vector < int > ans(200100);

bool ret = false;

void dfs(int root){

    M[root] = true;
    now.push_back(root);
    for (auto &x : gr[root]){
        if (!used[x]){
            used[x] = true;
            dfs(x);
        }
    }

}

void DFS(int root){

    COMP[root] = cont;
    NOW.push_back(root);
    for (auto &x : inv[root]){
        if (M[x] && !USED[x]){
            USED[x] = true;
            DFS(x);
        }
    }

}

void bfs(){

    while (!Q.empty()){

        int Now = Q.front();
        Q.pop();
        ord_top.push_back(Now);

        for (auto &x : GR[Now]){
            enter[x]--;
            if (!enter[x]){
                Q.push(x);
            }
        }

    }

}

int main() {

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n , m;
    cin>>n>>m;

    for (int i=1; i<=m; i++){

        int a , b;
        cin>>a>>b;

        //-a -> b
        //-b -> a

        int A = -a;
        int B = -b;

        if (a < 0){
            a = -a;
            a += n;
        }
        else{
            A = -A;
            A += n;
        }
        if (b < 0){
            b = -b;
            b += n;
        }
        else{
            B = -B;
            B += n;
        }

        gr[A].push_back(b);
        gr[B].push_back(a);

        inv[b].push_back(A);
        inv[a].push_back(B);

    }

    //componente conexe

    for (int i=1; i<=2*n; i++){
        if (!used[i]){
            now.clear();
            M.clear();
            used[i] = true;
            dfs(i);
            for (auto &x : now){
                if (!USED[x]){
                    NOW.clear();
                    cont++;
                    USED[x] = true;
                    DFS(x);
                    comp[cont] = NOW;
                }
            }
        }
    }

    /*cout<<cont<<'\n';

    for (int i=1; i<=cont; i++){
        for (auto &x : comp[i]){
            cout<<x<<" ";
        }
        cout<<'\n';
    }*/

    for (int i=n+1; i<=n; i++){
        if (COMP[i] == COMP[i-n]){
            ret = true;
        }
    }

    //ordine topologica

    for (int i=1; i<=cont; i++){
        for (auto &x : comp[i]){
            for (auto &y : gr[x]){
                if (COMP[y] != i){
                    GR[i].push_back(COMP[y]);
                    enter[COMP[y]]++;
                }
            }
        }
    }

    for (int i=1; i<=cont; i++){
        if (!enter[i]){
            Q.push(i);
        }
    }

    bfs();

    /*for (auto &i : ord_top){
        cout<<i<<" ";
    }*/

    //raspuns

    for (int i=1; i<=cont; i++){
        ans[i] = -1;
    }

    for (auto &i : ord_top){
        if (ans[i] == -1){
            ans[i] = 0;
        }
        for (auto &x : comp[i]){
            int opus;
            if (x > n){
                opus = x - n;
            }
            else{
                opus = x + n;
            }

            if (ans[COMP[opus]] == -1){
                ans[COMP[opus]] = ans[i] ^ 1;
            }
            else{
                if (ans[COMP[opus]] == ans[i]){
                    ret = true;
                }
            }
            for (auto &y : gr[x]){
                if (ans[i] == 1){
                    if (ans[COMP[y]] == 0){
                        ret = true;
                    }
                    ans[COMP[y]] = 1;
                }
            }

        }

    }

    if (ret){
        cout<<-1;
    }
    else {
        for (int i=1; i<=n; i++){
            cout<<ans[COMP[i]]<<" ";
        }
    }

    return 0;
}