Cod sursa(job #2633593)

Utilizator stefan.popescuPopescu Stefan stefan.popescu Data 7 iulie 2020 20:45:30
Problema 2SAT Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
ifstream in ("2sat.in");
ofstream out("2sat.out");
int n, m, x, y, compAct, mom, addy;
vector < vector <int> > muchii, componente;
vector <int> disc, low, componentaTata, permutare;
stack <int> stk;
vector <bool> atins;
vector <char> realVal;
void tarjrec(int nod)
{
    low[nod+addy]=disc[nod+addy] = ++mom;
    stk.push(nod);
    for(auto & x : muchii[nod+addy])
    {
        if(disc[x+addy]==-1)
        {
            tarjrec(x);
            low[nod+addy]=min(low[nod+addy], low[x+addy]);
        }
        else
            low[nod+addy]=min(low[nod+addy], disc[x+addy]);
    }

    if(low[nod+addy]==disc[nod+addy])
    {
        componente.push_back( vector<int>());
        while(!stk.empty()&&stk.top()!=nod)
        {
            componente.back().push_back(stk.top());
            disc[stk.top()+addy]+=2*n; ///ca sa scap de onStack
            componentaTata[stk.top()+addy]=componente.size();
            stk.pop();
        }
        componente.back().push_back(stk.top());
        disc[stk.top()+addy]+=2*n; ///ca sa scap de onStack
        componentaTata[stk.top()+addy]=componente.size();
        stk.pop();
    }
}
inline void Tarjan()
{
    for(int i=-n; i<=-1; i++)
        if(disc[i+addy]==-1)
            mom=0, tarjrec(i);

    for(int i=1; i<=n; i++)
        if(disc[i+addy]==-1)
            mom=0, tarjrec(i);
}
void toprec(int nod)
{
    atins[nod+addy]=true;

    for(auto & x : muchii[nod+addy])
        if(!atins[x+addy])
            toprec(x);

    permutare.push_back(nod);
}
inline void Topologica()
{
    for(int i=-n; i<=-1; i++)
        if(!atins[i+addy])
            toprec(i);

    for(int i=1; i<=n; i++)
        if(!atins[i+addy])
            toprec(i);

    reverse(permutare.begin(), permutare.end());
}
void colorare(int nod, int culoare)
{
    //cout<<nod<<" "<<culoare<<"\n";
    int comp=componentaTata[nod+addy]-1;

    realVal[nod+addy]=culoare;
    realVal[-nod+addy]=3-culoare;

    for(auto & x : componente[comp])
        if(realVal[x+addy]==0)
            colorare(x, culoare);

    comp=componentaTata[-nod+addy]-1;

    for(auto & x : componente[comp])
        if(realVal[x+addy]==0)
            colorare(x, 3-culoare);

    for(auto & x : muchii[nod+addy])
        if(realVal[x+addy]==0)
            colorare(x, culoare);

    for(auto & x : muchii[-nod+addy])
        if(realVal[x+addy]==0)
            colorare(x, 3-culoare);
}
int main()
{
    in>>n>>m;
    addy=n;
    muchii.resize(2*n+1); componentaTata.resize(2*n+1, -1); atins.resize(2*n+1, false);
    disc.resize(2*n+1, -1); low.resize(2*n+1, -1); realVal.resize(2*n+1, 0);
    for(int i=1; i<=m; i++)
    {
        in>>x>>y;
        muchii[-x+addy].push_back(y);
        muchii[-y+addy].push_back(x);
    }

    Tarjan();


    for(int i=1; i<=n; i++)
        if(componentaTata[i+addy]==componentaTata[-i+addy])
        {out<<"-1"; return 0;}

    Topologica();

    /*for(auto & x: permutare)
        cout<<x<<" ";*/


    /*for(auto & vec: componente)
    {
        for(auto & x : vec)
            cout<<x<<" ";
        cout<<"\n";
    }*/

    for(auto & val: permutare)
        if(realVal[val]==0)
            colorare(val, 1);

    for(int i=1; i<=n; i++)
        out<<(bool) (realVal[i+addy]-1)<<"\n";

    return 0;
}