Cod sursa(job #1547901)

Utilizator iulianbuteBute Iulian iulianbute Data 10 decembrie 2015 01:32:07
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 5.33 kb
#include <fstream>
#define MAX_Noduri 100001
#define MAX_Muchii 200001

using namespace std;

struct noduri {
    int nume;
    int valoare;
    int vizitat;
    int culoare;
    int nrVecini;
    int arc[MAX_Muchii+1];
};
noduri graf[MAX_Noduri+1], grafT[MAX_Noduri+1];

int nrVariabile, nrConjunctii, nrNoduri, nrArce, satisfiabila;
int parc1[MAX_Noduri+1], indexParc1, culoareCurenta, indParc1;

int dfs(int nod)
{
    graf[nod].vizitat=1;
    for(int indexVecin=0; indexVecin<graf[nod].nrVecini;indexVecin++)
    {
        int vecin; vecin=graf[nod].arc[indexVecin];
        if(!graf[vecin].vizitat) dfs(vecin);
    }
    parc1[indexParc1++]=nod;
    return 0;
}

int coloreaza(int indexStartParc1, int nodStartCiclu, int indexCapatParc1)
{
    if (indexStartParc1>indexCapatParc1) return 0;
    int indexCurent, nodCurent, gasitNodStartCiclu=0;
    indexCurent=indexCapatParc1;
    do
    {
        nodCurent=parc1[indexCurent];
        if(!gasitNodStartCiclu)
            graf[nodCurent].culoare=grafT[nodCurent].culoare=indexCapatParc1;
            else
                graf[nodCurent].culoare=grafT[nodCurent].culoare=indexCurent;
        if(nodCurent==nodStartCiclu) gasitNodStartCiclu=1;
        indexCurent--;
    } while (indexCurent>=indexStartParc1);

    return 0;
}

int cautaCicluri(int indexInParcurgere1)
{
    if((indexInParcurgere1>=nrNoduri)||(indexInParcurgere1<0)) return 0;
    int nodCurent, nodVecin, nodUrmator, gasitNodUrmator=0, nodAnteriorGasit=0;
    nodCurent=parc1[indexInParcurgere1];
    grafT[nodCurent].vizitat=1;
    nodUrmator=parc1[indexInParcurgere1+1];
    for(int indexNodVecin=0; indexNodVecin<grafT[nodCurent].nrVecini; indexNodVecin++)
    {
        nodVecin=grafT[nodCurent].arc[indexNodVecin];
        if(grafT[nodVecin].vizitat) nodAnteriorGasit=nodVecin;
        if(nodVecin==nodUrmator) gasitNodUrmator=1;
    }
    if( (nodAnteriorGasit) || (!gasitNodUrmator) ) coloreaza(indParc1,nodAnteriorGasit,indexInParcurgere1);
    if(gasitNodUrmator) cautaCicluri(++indexInParcurgere1);

    return 0;
}

int negatie(int indexNod)    // returneaza indexul nodului negat al nodului indexNod
{
    if(indexNod<nrVariabile) return indexNod+nrVariabile;  //indexNod e de la un nod negat
    if(indexNod>nrVariabile) return indexNod-nrVariabile;  //indexNod e de la un nod nenegat
    return 0;
}

int asignare()
{
    int valAdevUrm=0, NvalAdevUrm=1, valAdevPrez=1, nodCurent, nodUrmator;
    for(indexParc1=0; indexParc1<nrNoduri; indexParc1++)
    {
        nodCurent=parc1[indexParc1];
        nodUrmator=parc1[indexParc1+1];
        if (graf[nodCurent].valoare==-1)
            {graf[nodCurent].valoare=valAdevUrm; graf[negatie(nodCurent)].valoare=NvalAdevUrm;}
        valAdevPrez*=graf[nodCurent].valoare;
        if (graf[nodCurent].culoare!=graf[nodUrmator].culoare)
            if (valAdevPrez==1) {valAdevUrm=1; NvalAdevUrm=0;}
    }

    return 0;
}

int main()
{
    ifstream in;
    in.open("2sat.in");
    in>>nrVariabile>>nrConjunctii;

    //  INITIALIZARE
    nrNoduri=nrVariabile*2; nrVariabile++; nrNoduri++;
    nrArce=nrConjunctii*2;
    for(int nodCurent=1;nodCurent<=nrNoduri;nodCurent++)
    {
        graf[nodCurent].nume=nodCurent-nrVariabile;
        grafT[nodCurent].nume=nodCurent-nrVariabile;
        graf[nodCurent].valoare=-1;
        grafT[nodCurent].valoare=-1;

//  INITIALIZARI CARE SE FAC SI IMPLICIT
//        graf[nodCurent].culoare=graf[nodCurent].vizitat=graf[nodCurent].nrVecini=0;
//        for(int vecin=0;vecin<=nrArce;vecin++) graf[nodCurent].arc[vecin]=0;
//        grafT[nodCurent].culoare=grafT[nodCurent].vizitat=grafT[nodCurent].nrVecini=0;
//        for(int vecin=0;vecin<=nrArce;vecin++) grafT[nodCurent].arc[vecin]=0;
//        parc1[nodCurent]=0;
    }

    // CITIRE CONJUNCTII
    int varA, varB, NvarA, NvarB;
    for(int conjCurenta=0; conjCurenta<nrConjunctii; conjCurenta++)
    {
        in>>varA>>varB;
        NvarA=-varA+nrVariabile; NvarB=-varB+nrVariabile;
        varA+=nrVariabile; varB+=nrVariabile;
        // !A->B
        graf [NvarA].arc[graf [NvarA].nrVecini++]= varB;
        grafT[ varB].arc[grafT[ varB].nrVecini++]=NvarA;
        // !B->A
        graf [NvarB].arc[graf [NvarB].nrVecini++]= varA;
        grafT[ varA].arc[grafT[ varA].nrVecini++]=NvarB;
    }
    in.close();

    for (int nodCurent=1; nodCurent<=nrNoduri;nodCurent++)
    if( (nodCurent!=nrVariabile) && (!graf[nodCurent].vizitat) ) dfs(nodCurent);

    for(indParc1=0; indParc1<indexParc1; indParc1++)
    {
        int nodCurent;
        nodCurent=parc1[indParc1];
        if (graf[nodCurent].culoare==0)
                cautaCicluri(indParc1);
    }

    satisfiabila=1;
    for(int index=1;index<nrVariabile; index++)
    {
        NvarA=nrVariabile-index;
         varA=nrVariabile+index;
        if(graf[varA].culoare==graf[NvarA].culoare) satisfiabila=0;
    }

    int temp;
    for(int i=0; i<nrVariabile-1; i++)
    {
        temp=parc1[i];
        parc1[i]=parc1[nrNoduri-i-2];
        parc1[nrNoduri-i-2]=temp;
    }

    ofstream out;
    out.open("2sat.out");
    if(satisfiabila)
    {
        asignare();
        for(int nodCurent=nrVariabile+1; nodCurent<=nrNoduri; nodCurent++)
             out<<graf[nodCurent].valoare<<" ";
    } else out<<"-1";
    out.close();
    return 0;
}