Cod sursa(job #2298144)

Utilizator XDDDDariusPetean Darius XDDDDarius Data 7 decembrie 2018 16:45:39
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fi("2sat.in");
ofstream fo("2sat.out");
int n;  /// numarul de variabile
int m;  /// numarul de propozitii
vector <int> ADJ[200005];
vector <int> ADJT[200005];
int S[200005],k;
int VIZ[200005];
int nrct;

void df(int v)
{
    vector <int> :: iterator it;
    VIZ[v]=1;
    for (it=ADJ[v].begin();it!=ADJ[v].end();it++)
    {
        int varf;
        varf=(*it);
        if (VIZ[varf]==0)
            df(varf);
    }
    S[++k]=v;
}

void dft(int v)
{
    vector <int> :: iterator it;
    VIZ[v]=nrct;
    for (it=ADJT[v].begin();it!=ADJT[v].end();it++)
    {
        int varf;
        varf=(*it);
        if (VIZ[varf]==0)
            dft(varf);
    }
}

void depth(int v)
{
    vector <int> :: iterator it;
    VIZ[v]=0;
    for (it=ADJT[v].begin();it!=ADJT[v].end();it++)
    {
        int varf;
        varf=(*it);
        if (VIZ[varf]==-1 && VIZ[varf^1]==-1)
            depth(varf);
    }
}

int main()
{
    fi>>n>>m;
    for (int i=1;i<=m;i++)
    {
        int x,y;
        fi>>x>>y;
        if (x>0)
            x=x*2;
        else
            x=-x*2+1;
        if (y>0)
            y=y*2;
        else
            y=-y*2+1;
        /// apar doua arce in graful inferentelor
        ADJ[y^1].push_back(x);
        ADJ[x^1].push_back(y);
        ADJT[x].push_back(y^1);
        ADJT[y].push_back(x^1);
    }
    /// varfurile sunt numerotate de la 2 la 2*n+1
    /// algoritmul Kosaraju-Sharir
    for (int i=2;i<=2*n+1;i++)
        if (VIZ[i]==0)
            df(i);
    for (int i=2;i<=2*n+1;i++)
        VIZ[i]=0;
    nrct=0;
    for (int i=k;i>=1;i--)
        if (VIZ[S[i]]==0)
        {
            nrct++;
            dft(S[i]);
        }
    /// se verifica daca exista x si -x marcate la fel
    int t;
    t=1;
    for (int i=2;i<=2*n;i=i+2)
        if (VIZ[i]==VIZ[i^1])
            t=0;
    if (t==0)
    {
        fo<<-1;
        fi.close();
        fo.close();
        return 0;
    }
    /// se atribuie valori necunoscutelor
    for (int i=2;i<=2*n+1;i++)
        VIZ[i]=-1;
    for (int i=k;i>=1;i--)
        if (VIZ[S[i]]==-1 && VIZ[S[i]^1]==-1)
            depth(S[i]);
    /// afisare
    for (int i=2;i<=2*n;i=i+2)
        if (VIZ[i]!=-1)
            fo<<VIZ[i]<<" ";
        else
            fo<<1-VIZ[i^1]<<" ";
    fi.close();
    fo.close();
    return 0;
}