Cod sursa(job #2875783)

Utilizator alexmorosanuMorosanu Alexandru alexmorosanu Data 22 martie 2022 12:34:35
Problema 2SAT Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.37 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);
}
bool sol[200011];
queue <int> q1,q0;
int m,i,x[200011],y[200011],grad_to[200011],grad_from[200011],k0,k1,z,t;
vector <int> to[200011],from[200011];
int main()
{
    f>>n>>m;
    for(i=1;i<=m;i++)
    {
        f>>x[i]>>y[i];
        if(x[i]<0)
            x[i]=-x[i]+n;
        if(y[i]<0)
            y[i]=-y[i]+n;
        v[complement(x[i])].push_back(y[i]);
        v[complement(y[i])].push_back(x[i]);
    }
    for(i=1;i<=2*n;i++)
        if(fam[i]==0)
           tarjan(i);
    for(i=1;i<=n;i++)
        if(fam[i]==fam[i+n])
        {
            g<<-1;
            return 0;
        }
    for(i=1;i<=m;i++)
    {
        z=complement(x[i]);
        t=complement(y[i]);
        if(fam[z]!=fam[y[i]])
        {
            to[fam[z]].push_back(fam[y[i]]);
            grad_to[fam[z]]++;
            grad_from[fam[y[i]]]++;
            from[fam[y[i]]].push_back(fam[z]);
        }
        if(fam[t]!=fam[x[i]])
        {
            to[fam[t]].push_back(fam[x[i]]);
            grad_to[fam[t]]++;
            grad_from[fam[x[i]]]++;
            from[fam[x[i]]].push_back(fam[t]);
        }
    }
    //to[k] : k->
    //from[k] : k<-
    for(i=1;i<=nr;i++)
    {
        if(to[i].size()==0 && from[i].size()==0)
        {
            for(auto it=c[i].begin();it!=c[i].end();it++)
            {
                sol[*it]=0;
                sol[complement(*it)]=1;
            }
        }
        else
        if(grad_to[i]==0)
            q1.push(i);
        else
        if(grad_from[i]==0)
            q0.push(i);
    }
    while(q1.empty()==false)
    {
        k0=q0.front();
        q0.pop();
        k1=q1.front();
        q1.pop();
        for(auto it=c[k0].begin();it!=c[k0].end();it++)
                sol[*it]=0;
        for(auto it=c[k1].begin();it!=c[k1].end();it++)
                sol[*it]=1;
        for(auto it=to[k0].begin();it!=to[k0].end();it++)
        {
            grad_from[*it]--;
            if(grad_from[*it]==0 && grad_to[*it]!=0)
                q0.push(*it);
        }
        for(auto it=from[k1].begin();it!=from[k1].end();it++)
        {
            grad_to[*it]--;
            if(grad_to[*it]==0 && grad_from[*it]!=0)
                q1.push(*it);
        }
    }
    for(i=1;i<=m;i++)
    {
        if(sol[x[i]]==0 && sol[y[i]]==0)
        {
            g<<-1;
            return 0;
        }
    }
    for(i=1;i<=n;i++)
        g<<sol[i]<<" ";
    return 0;
}