Cod sursa(job #2693112)

Utilizator HumikoPostu Alexandru Humiko Data 4 ianuarie 2021 20:18:44
Problema 2SAT Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.07 kb
//Alex Postu

#include <bits/stdc++.h>

using namespace std;

static const int NMAX = 2e5+5;

int n, m;

vector <int> graph[NMAX];
vector <int> reversedGraph[NMAX];

bool f[NMAX];
bool truthValue[NMAX];

stack <int> path;

int flip (int vertex) {
    if ( vertex <= n ) {
        return vertex+n;
    }

    return vertex-n;
}

void normalise (int &vertex) {
    if ( vertex < 0 ) {
        vertex = n-vertex;
    }
}

void dfs (int vertex) {
    f[vertex] = 1;

    for ( auto x:graph[vertex] ) {
        if ( !f[x] ) {
            dfs(x);
        }
    }

    path.push(vertex);
}

bool reverseDfs (int vertex) {
    if ( truthValue[vertex] ) {
        return true;
    }

    f[vertex] = 1;
    truthValue[flip(vertex)] = 1;

    for ( auto x:reversedGraph[vertex] ) {
        if ( !f[x] ) {
            reverseDfs(x);
        }
    }

    return false;
}

int main() {
  #ifdef ONLINE_JUDGE
    freopen("input.in", "r", stdin);
    freopen("output.out", "w", stdout);
  #else
    freopen("2sat.in", "r", stdin);
    freopen("2sat.out", "w", stdout);
  #endif

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

    cin>>n>>m;
    for ( int i = 1; i <= m; ++i ) {
        int firstVertex, secondVertex;
        cin>>firstVertex>>secondVertex;

        normalise(firstVertex);
        normalise(secondVertex);

        graph[flip(firstVertex)].push_back(secondVertex);
        graph[flip(secondVertex)].push_back(firstVertex);

        reversedGraph[secondVertex].push_back(flip(firstVertex));
        reversedGraph[firstVertex].push_back(flip(secondVertex));
    }

    for ( int i = 1; i <= 2*n; ++i ) {
        if ( !f[i] ) {
            dfs(i);
        }
    }

    for ( int i = 1; i <= 2*n; ++i ) {
        f[i] = 0;
    }

    bool stopChecking = false;

    while ( path.size() ) {
        if ( !f[path.top()] && !f[flip(path.top())] ) {
            stopChecking = reverseDfs(path.top());
        }

        path.pop();

        if ( stopChecking ) {
            cout<<-1<<'\n';
            return 0;
        }
    }

    for ( int i = 1; i <= n; ++i ) {
        cout<<truthValue[i]<<" ";
    }
}