Cod sursa(job #2875845)

Utilizator alexmorosanuMorosanu Alexandru alexmorosanu Data 22 martie 2022 13:48:59
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.41 kb
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
ifstream f("2sat.in");
ofstream g("2sat.out");
int n;
int complement(int &x)
{
    if(x>n)
        return x-n;
    return x+n;
}
stack <int> st;
int nr,fam[200011];
vector <int> c[200011];
bool instk[200011];
void ctc(int k)
{
    nr++;
    int t;
    while(t!=k)
    {
        t=st.top();
        st.pop();
        instk[t]=0;
        fam[t]=nr;
        c[nr].push_back(t);
    }
}
vector <int> v[200011];
int index,when[200011],low[200011];
void tarjan(int k)
{
    index++;
    when[k]=low[k]=index;
    st.push(k);
    instk[k]=1;
    for(auto it=v[k].begin();it!=v[k].end();it++)
        if(when[*it]==0)
    {
        tarjan(*it);
        low[k]=min(low[k],low[*it]);
    }
        else
            if(instk[*it]==1)
                low[k]=min(low[k],low[*it]);
    if(when[k]==low[k])
        ctc(k);
}
int sol[200011];
queue <int> q;
int m,i,x,y,grad[200011],k,z,t;
int main()
{
    f>>n>>m;
    for(i=1;i<=m;i++)
    {
        f>>x>>y;
        if(x<0)
            x=-x+n;
        if(y<0)
            y=-y+n;
        v[complement(x)].push_back(y);
        v[complement(y)].push_back(x);
    }
    for(i=1;i<=2*n;i++)
        if(fam[i]==0)
           tarjan(i);
    for(i=1;i<=n;i++)
    {
        sol[i]=-1;
        if(fam[i]==fam[i+n])
        {
            g<<-1;
            return 0;
        }
    }
    for(i=1;i<=2*n;i++)
        for(auto it=v[i].begin();it!=v[i].end();it++)
        if(fam[i]!=fam[*it])
            grad[fam[*it]]++;
    for(i=1;i<=nr;i++)
        if(grad[i]==0)
            q.push(i);
    while(q.empty()==false)
    {
        k=q.front();
        q.pop();
        for(auto it=c[k].begin();it!=c[k].end();it++)
        {
            z=*it;
            if(z>n)
                z=z-n;
            if(sol[z]==-1)
            {
                if(*it<=n)
                    sol[z]=0;
                else
                    sol[z]=1;
            }
        }
        for(auto it=c[k].begin();it!=c[k].end();it++)
            for(auto j=v[*it].begin();j!=v[*it].end();j++)
        {
            if(fam[*it]!=fam[*j])
            {
                grad[fam[*j]]--;
                if(grad[fam[*j]]==0)
                    q.push(fam[*j]);
            }
        }
    }
    for(i=1;i<=n;i++)
        g<<sol[i]<<" ";
    return 0;
}