Pagini recente » Cod sursa (job #2628325) | Cod sursa (job #2192239) | Cod sursa (job #2686553) | Cod sursa (job #1494923) | Cod sursa (job #1547901)
#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;
}