Cod sursa(job #1656924)

Utilizator GinguIonutGinguIonut GinguIonut Data 19 martie 2016 23:13:51
Problema 2SAT Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 3.5 kb
#include <fstream>
#include <vector>
#include <string.h>
#include <queue>

#define nMax 100005
#define pb push_back

using namespace std;
ifstream fin("2sat.in");
ofstream fout("2sat.out");

int variables, expressions, impossible, n;
int discover[2*nMax], vct[2*nMax], value[nMax], scc_in_deg[2*nMax];
bool viz[2*nMax];
vector<int> G[2*nMax], GT[2*nMax], scc;
vector<vector<int> > sccs;
queue<int> Q;
inline int abs(int x)
{
    return (x<0) ? -x : x;
}
inline int idx(int x)
{
    return (x<0) ? abs(x)+variables : x;
}
inline int non(int x)
{
    return (x>variables) ? x-variables : x+variables;
}

void read()
{
    int x, y;
    fin>>variables>>expressions;

    for(int i=1;i<=expressions;i++)
    {
        fin>>x>>y;
        G[non(idx(x))].pb(idx(y));
        GT[idx(y)].pb(non(idx(x)));
        G[non(idx(y))].pb(idx(x));
        GT[idx(x)].pb(non(idx(y)));
    }
}
void dfs(int node)
{
    viz[node]=1;

    for(vector<int>::iterator it=G[node].begin();it!=G[node].end();it++)
    {
        int fiu=*it;
        if(!viz[fiu])
            dfs(fiu);
    }

    discover[++discover[0]]=node;
}
void dfst(int node)
{
    viz[node]=1;
    scc.pb(node);

    for(vector<int>::iterator it=GT[node].begin();it!=GT[node].end();it++)
    {
        int fiu=*it;
        if(!viz[fiu])
            dfst(fiu);
    }
}
void compute_sccs()
{
    for(int i=1;i<=2*variables;i++)
        if(!viz[i])
            dfs(i);

    memset(viz, 0, sizeof(viz));
    for(int i=2*variables;i>=1;i--)
    {
        if(!viz[discover[i]])
        {
            scc.clear();
            dfst(discover[i]);
            for(vector<int>::iterator it=scc.begin();it!=scc.end();it++)
            {
                int fiu=*it;
                vct[fiu]=sccs.size();
            }
            sccs.pb(scc);
        }
    }
}
void verif()
{
    for(int i=1;i<=variables;i++)
        if(vct[i]==vct[non(i)])
            impossible=true;
}
void solve()
{
    memset(value, -1, sizeof(value));
    compute_sccs();
    verif();
    if(!impossible)
    {
        for(int i=1;i<=2*variables;i++)
        {
            for(vector<int>::iterator it=G[i].begin();it!=G[i].end();it++)
            {
                int fiu=*it;
                if(vct[i]!=vct[fiu])
                    scc_in_deg[vct[fiu]]++;
            }
        }

        for(int i=0;i<sccs.size();i++)
            if(scc_in_deg[i]==0)
                Q.push(i);

        while(!Q.empty())
        {
            int node=Q.front();
            Q.pop();
            for(vector<int>::iterator it=sccs[node].begin();it!=sccs[node].end();it++)
            {
                int fiu=(*it>variables) ? *it-variables : *it;
                if(value[fiu]==-1)
                    value[fiu]=(*it <= variables) ? 0 : 1;
            }

            for(vector<int>::iterator it=sccs[node].begin();it!=sccs[node].end();it++)
            {
                for(vector<int>::iterator lit=G[*it].begin();lit!=G[*it].end();lit++)
                {
                    int fiu=*lit;
                    if(vct[*it]!=vct[fiu])
                    {
                        scc_in_deg[vct[fiu]]--;
                        if(!scc_in_deg[vct[fiu]])
                            Q.push(vct[fiu]);
                    }
                }
            }
        }
        for(int i=1;i<=variables;i++)
            fout<<value[i]<<" ";
    }
    else
        fout<<0;
}
int main()
{
    read();
    solve();
    return 0;
}