Cod sursa(job #2265325)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 20 octombrie 2018 22:44:05
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.46 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

int N, M;

namespace _2SAT
{
    int N2, C, I;
    bool solution;
    int idx[200005], low[200005], instk[200005];
    int val[200005], scc[200005];
    vector<int> stk, edg[200005];

    void init()
    {
        N2 = 2 * N;
        for(int i = 0; i < N2; i++)
        {
            edg[i].clear();
            val[i] = 0;
        }
    }

    int node(int x) { return (x < 0 ? (-x * 2 - 1) : (2 * x - 2)); }

    void addEdge(int x, int y)
    {
        edg[node(x)].push_back(node(y));
    }

    void addCondition(int x, int y)
    {
        addEdge(-x, y);
        addEdge(-y, x);
    }

    void setValue(int x, int v)
    {
        if(v == 0)  addEdge(x, -x);
        if(v == 1)  addEdge(-x, x);
    }

    void DFS(int nod)
    {
        if(idx[nod])  return;
        idx[nod] = low[nod] = ++I;
        stk.push_back(nod);
        instk[nod] = 1;
        for(auto nxt: edg[nod])
        {
            DFS(nxt);
            if(instk[nxt])  low[nod] = min(low[nod], low[nxt]);
        }
        if(low[nod] == idx[nod])
        {
            C++;
            while(stk.back() != nod)
            {
                scc[stk.back()] = C;
                instk[stk.back()] = 0;
                stk.pop_back();
            }
            scc[stk.back()] = C;
            instk[stk.back()] = 0;
            stk.pop_back();
        }
    }

    void getSCC()
    {
        stk.clear();
        for(int i = 0; i < N2; i++) idx[i] = 0;
        C = I = 0;
        for(int i = 0; i < N2; i++) DFS(i);
    }

    void solve()
    {
        solution = true;

        getSCC();

        for(int i = 1; i <= N; i++)
            if(scc[node(i)] == scc[node(-i)])
            {
                solution = false;
                return;
            }

        for(int i = 1; i <= N; i++)
            val[i] = (scc[node(i)] > scc[node(-i)] ? 0 : 1);
    }
}

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

    scanf("%d%d", &N, &M);
    _2SAT::init();
    for(int i = 1; i <= M; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        _2SAT::addCondition(x, y);
    }

    _2SAT::solve();
    if(_2SAT::solution == false)
    {
        printf("-1\n");
        exit(0);
    }
    for(int i = 1; i <= N; i++)
        printf("%d ", _2SAT::val[i]);

    return 0;
}