Cod sursa(job #1067286)

Utilizator romircea2010FMI Trifan Mircea Mihai romircea2010 Data 26 decembrie 2013 17:36:40
Problema 2SAT Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.59 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#define NMax 100010
#define MMax 200010

using namespace std;

bool ans[2*NMax];
bool value[2*NMax];
int n21, nrc;
vector <int> G[2*NMax], GT[2*NMax], c[2*NMax], newG[2*NMax], newGT[2*NMax];
set <int> newGs[2*NMax];
int gradint[2*NMax], gradext[2*NMax];
int n, m;
int postordine[2*NMax], npostordine;
int comp[2*NMax];
bool viz[2*NMax];
bool existaSol;
queue <int> Q0, Q1;

inline int neg(const int &x)
{
    return n21-x;
}

void Read()
{
    ifstream f ("2sat.in");
    f>>n>>m;
    n21 = n+n+1;
    for (int i = 1; i<=m; ++i)
    {
        int x, y;
        f>>x>>y;
        if (x < 0)
            x = neg(abs(x));
        if (y < 0)
            y = neg(abs(y));
        G[neg(x)].push_back(y);
        G[neg(y)].push_back(x);
        GT[y].push_back(neg(x));
        GT[x].push_back(neg(y));
    }
    f.close();
}

inline void DFS(const int node)
{
    viz[node] = true;
    for (vector <int>::iterator it = G[node].begin(); it!=G[node].end(); ++it)
        if (!viz[*it])
            DFS(*it);
    postordine[++npostordine] = node;
}

inline void DFST(const int node)
{
    comp[node] = nrc;
    c[nrc].push_back(node);
    viz[node ] = false;
    for (vector <int>::iterator it = GT[node].begin(); it!=GT[node].end(); ++it)
        if (viz[*it])
            DFST(*it);
}

void Solve()
{
    existaSol = true;
    int i;
    for (i=1; i < n21; ++i)
        if (!viz[i])
            DFS(i);
    for (i = n21 - 1; i; --i)
        if (viz[postordine[i]])
        {
            ++nrc;
            DFST(postordine[i]);
        }
    for (i=1; i<=n; ++i)
        if (comp[i] == comp[neg(i)])
        {
            existaSol = false;
            return ;
        }
    for (i = 1; i<=nrc; ++i)
        for (vector <int>::iterator it = c[i].begin(); it != c[i].end(); ++it)
            for (vector <int>::iterator it2 = G[*it].begin(); it2 != G[*it].end(); ++it2)
                if (comp[*it2] != i)
                    newGs[i].insert(comp[*it2]);

    for (i = 1; i<=nrc; ++i)
    {
        gradext[i] = newGs[i].size();
        for (set <int>::iterator it = newGs[i].begin(); it!=newGs[i].end(); ++it)
        {
            newG[i].push_back(*it);
            newGT[*it].push_back(i);
            ++gradint[*it];
        }
    }
    for (i=1; i<=nrc; ++i)
    {
        if (gradint[i] == 0 && gradext[i] != 0)
            Q0.push(i);
        if (gradext[i] == 0 && gradint[i] != 0)
            Q1.push(i);
    }
    int nodesleft = nrc;
    bool existamodif = true;
    queue <int> Qaux;
    while (nodesleft && existamodif)
    {
        existamodif = false;

        while (!Q0.empty())
        {
            --nodesleft;
            int node = Q0.front();
            gradext[node] = 0;
            value[node] = false;
            for (vector <int>::iterator it = newG[node].begin(); it!=newG[node].end(); ++it)
            {
                --gradint[*it];
                if (gradint[*it] == 0 && gradext[*it] != 0)
                    Qaux.push(*it);
            }
            Q0.pop();
        }
        while (!Qaux.empty())
        {
            Q0.push(Qaux.front());
            Qaux.pop();
        }

        while (!Q1.empty())
        {
            --nodesleft;
            int node = Q1.front();
            gradint[node] = 0;
            value[node] = true;
            for (vector <int>::iterator it = newGT[node].begin(); it!=newGT[node].end(); ++it)
            {
                --gradext[*it];
                if (gradext[*it] == 0 && gradint[*it] != 0)
                    Qaux.push(*it);
            }
            Q1.pop();
        }
        while (!Qaux.empty())
        {
            Q1.push(Qaux.front());
            Qaux.pop();
        }

        if (!Q0.empty() && !Q1.empty())
            existamodif = true;
    }
    if (nodesleft != 0)
    {
        existaSol = false;
        return ;
    }
    for (i = 1; i<=nrc; ++i)
        for (vector <int>::iterator it = c[i].begin(); it!=c[i].end(); ++it)
            ans[*it] = value[i];
    for (i = 1; i<=n; ++i)
        if (ans[i] == ans[neg(i)])
        {
            existaSol = 0;
            return ;
        }
}

void Write()
{
    ofstream g("2sat.out");
    if (!existaSol)
        g<<"-1";
    else
        for (int i=1; i<=n; ++i)
            if (ans[i])
                g<<"1 ";
            else
                g<<"0 ";
    g<<"\n";
    g.close();

}

int main()
{
    Read();
    Solve();
    Write();
    return 0;
}