Cod sursa(job #1122264)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 25 februarie 2014 17:16:00
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <cstring>

using namespace std;

const int Nmax = 100001;
const int Mmax = 200001;

vector <int> G[Nmax * 2], GT[Nmax * 2], SCC[Nmax * 2], DAG[Nmax * 2];
int sol[Nmax * 2];
int vis[Nmax * 2];
stack <int> S;

int N, M, EXIST_SOL = 1;

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

void DFS( int nod )
{
    vis[nod] = 1;

    for ( auto x: G[nod] )
            if ( !vis[x] )
                    DFS( x );

    S.push( nod );
}

void DFST( int nod )
{
    if ( sol[nod] ) EXIST_SOL = 0;

    vis[nod] = 1;
    sol[ neg( nod ) ] = 1;

    for ( auto x: GT[nod] )
            if ( !vis[x] )
                    DFST( x );
}

void SAT2()
{
    for ( int i = 1; i <= 2 * N; ++i )
            if ( !vis[i] )
                    DFS( i );

    memset( vis, 0, sizeof( vis ) );

    while ( S.size() )
    {
        int nod = S.top();
        S.pop();

        if ( vis[nod] == 0 && vis[ neg( nod ) ] == 0 )
                DFST( nod );
    }
}

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

    scanf("%d %d", &N, &M);

    for ( int i = 1, x, y; i <= M; ++i )
    {
        scanf("%d %d", &x, &y);

        if ( x < 0 ) x = -x + N;
        if ( y < 0 ) y = -y + N;

        G[ neg( x ) ].push_back( y );
        G[ neg( y ) ].push_back( x );

        GT[y].push_back( neg( x ) );
        GT[x].push_back( neg( y ) );
    }

    SAT2();

    if ( EXIST_SOL )
    {
        for ( int i = 1; i <= N; ++i )
        {
            printf("%d ", sol[i]);
        }
    }
    else
    {
        printf("-1");
    }

    return 0;
}