Cod sursa(job #1575337)

Utilizator iulian_f2kGuraliuc Iulian iulian_f2k Data 21 ianuarie 2016 13:41:42
Problema 2SAT Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.65 kb
#include <iostream>//Foloseste Kosaraju
#include <fstream>//De ce unele teste pe care iau Gresit afiseaza doar 1 atunci cand eu gasesc o solutie?
#include <vector>
#include <stack>
#define NMAX 100005
using namespace std;
vector<int> Comp[NMAX*2],L,G[NMAX*2],Gt[NMAX*2];

bool visited[NMAX*2],val[NMAX*2],solved,mark[NMAX*2];
int lenghtL,NrComp,N,M,comp[NMAX*2];

void read()
{
    scanf("%d%d", &N, &M);
    int a,b,conva,convb,notconva,notconvb;

    for(int i=1; i<=M; i++) // G: -N, ..., -4, -3, -2, -1, 1, 2, 3, 4, ..., N
    {
        scanf("%d%d", &a, &b);
        if(a<0){
            conva=N+a+1;
            notconva=N+(a*(-1));
        }
        else{
            conva=N+a;
            notconva=N-a+1;
        }
        if(b<0){
            convb=N+b+1;
            notconvb=N+(b*(-1));
        }
        else{
            convb=N+b;
            notconvb=N-b+1;
        }
        G[notconva].push_back(convb);
        Gt[convb].push_back(notconva);
        G[notconvb].push_back(conva);
        Gt[conva].push_back(notconvb);
    }
}
void visit(int u)
{
    if(visited[u])
        return;

    visited[u]=1;
    for(int i=0; i<G[u].size(); ++i)
    //for(int i=1; i<=G[u][0]; ++i)
        visit(G[u][i]);
    L.push_back(u);
}
void createComponent(int u,int componenta)
{
    comp[u]=componenta;
    Comp[componenta].push_back(u);
    for(int i=0; i<Gt[u].size(); ++i)
    //for(int i=1; i<=Gt[u][0]; ++i)
    {
        int nod=Gt[u][i];
        if(!comp[nod])
            createComponent(nod,componenta);
    }
}
bool Contradictii()//verifica daca exista contradictii
{
    int poz=N+1,neg=N;
    for(int i=1;i<N;i++){
        if(val[poz]==val[neg] && mark[poz]==1 && mark[neg]==1)
            return 1;
        poz+=1;
        neg-=1;
    }
    return 0;
}
void afisare()
{
    for(int i=N+1;i<=N*2;i++)
        cout<<val[i]<<' ';
    cout<<'\n';
}
void assignValues(int Componenta, bool valoare)
//se pleaca de la ultima componenta si se atribuie valori fiecarei componente
{   //daca am dat valori tuturor componentelor
    if(Componenta==0){
        //daca nu exista contradictii
        if(Contradictii()==0)
            {solved=1;afisare();}
    }
    else
    //daca inca nu am gasit o solutie
    if(!solved)
    {   //atribuirea propriu-zisa a valorilor
        for(int i=0;i<Comp[Componenta].size();i++){
            val[Comp[Componenta][i]]=valoare;
            //marchez valorile prin care am trecut pana acum in parcurgere ca sa stiu unde sa caut contradictii
            mark[Comp[Componenta][i]]=1;
        }
        if(Contradictii()==0){
            if(valoare==0)
                assignValues(Componenta-1, 0);
            else{
                assignValues(Componenta-1, 0);
                assignValues(Componenta-1, 1);
            }

        for(int i=0;i<Comp[Componenta].size();i++)
            mark[Comp[Componenta][i]]=0;
        }
    }
}
int main()
{
    freopen("2sat.in","rt",stdin);
    freopen("2sat.out","wt",stdout);
    read();
    //sortare topologica Kosaraju
    for(int u=1; u<=2*N; u++)
        visit(u);

    //crearea componentelor conexe
    lenghtL=L.size()-1;
    while(lenghtL>-1)
    {
        if(comp[L[lenghtL]]==0)
            createComponent(L[lenghtL],++NrComp);
        lenghtL--;
    }
    /*for(int i=0;i<2*N;i++)//afisarea sortarii topologice
        cout<<L[i]<<' ';
    cout<<'\n';
    for(int i=1; i<=NrComp; i++)//afisarea componentelor
    {
        for(int j=0; j<Comp[i].size(); j++)
            cout<<Comp[i][j]<<' ';
        cout<<'\n';
    }*/
    assignValues(NrComp,1);
    if(solved==0)
        cout<<"-1\n";
}