Cod sursa(job #663684)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 18 ianuarie 2012 20:28:18
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <cstdio>
#include <cstring>
#include <vector>

#define NMax 200005

using namespace std;

vector <int> G[NMax], GT[NMax];
int N, TSort[NMax], Solution[NMax];
bool Used[NMax];

inline int Non (int X)
{
    if (X<=N)
    {
        return X+N;
    }
    return X-N;
}

void Read ()
{
    freopen ("2sat.in", "r", stdin);
    int M;
    scanf ("%d %d", &N, &M);
    for (; M>0; --M)
    {
        int X, Y;
        scanf ("%d %d", &X, &Y);
        if (X<0)
        {
            X=N-X;
        }
        if (Y<0)
        {
            Y=N-Y;
        }
        G[Non (X)].push_back (Y);
        G[Non (Y)].push_back (X);
        GT[X].push_back (Non (Y));
        GT[Y].push_back (Non (X));
    }
}

void Print ()
{
    freopen ("2sat.out", "w", stdout);
    if (Solution[0]==-1)
    {
        printf ("-1\n");
        return;
    }
    for (int i=1; i<=N; ++i)
    {
        printf ("%d ", Solution[i]);
    }
    printf ("\n");
}

inline void DFP (int X)
{
    Used[X]=true;
    for (vector <int> :: iterator V=G[X].begin (); V!=G[X].end (); ++V)
    {
        if (!Used[*V])
        {
            DFP (*V);
        }
    }
    TSort[++TSort[0]]=X;
}

inline void DFM (int X)
{
    if (Solution[X]==1)
    {
        Solution[0]=-1;
        return;
    }
    Used[X]=true;
    Solution[Non (X)]=1;
    for (vector <int> :: iterator V=GT[X].begin (); V!=GT[X].end (); ++V)
    {
        if (!Used[*V])
        {
            DFM (*V);
        }
    }
}

void Kosaraju ()
{
    for (int i=1; i<=N+N; ++i)
    {
        if (!Used[i])
        {
            DFP (i);
        }
    }
    memset (Used, 0, sizeof (Used));
    for (int i=TSort[0]; i>0; --i)
    {
        if (!Used[TSort[i]] and !Used[Non (TSort[i])])
        {
            DFM (TSort[i]);
        }
    }
}

int main()
{
    Read ();
    Kosaraju ();
    Print ();
    return 0;
}