Cod sursa(job #1171869)

Utilizator silvatheviprersilviu catioiu silvatheviprer Data 16 aprilie 2014 15:13:16
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.57 kb
#include<stdio.h>
#define non(x) x<=n?x+n:x-n
#define nod(x) x>0?x:n-x
#define NN 200010
struct nod{int vec;nod *urm;};
nod *Out[NN],*In[NN],*CT[NN],*S,*E;
int n,m,NC,LOW[NN],DFN[NN],VIZ[NN],CC[NN],num,*GRDC,*VALC,*VAL;
void read(),solve(),visit(int p);
int main()
{
    read();
    solve();
    return 0;
}
void read()
{
    int i,x,y,X,Y;
    nod *p;
    freopen("2sat.in","r",stdin);
    freopen("2sat.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        if(x+y==0)continue;
        x=nod(x);X=non(x);
        y=nod(y);Y=non(y);
        p=new nod;p->vec=x;p->urm=Out[Y];Out[Y]=p;
        p=new nod;p->vec=y;p->urm=Out[X];Out[X]=p;
        //p=new nod;p->vec=X;p->urm=In[y];In[y]=p;
        //p=new nod;p->vec=Y;p->urm=In[x];In[x]=p;

    }
}
void solve()
{
    int i,cf,ct;nod *p,*q,*r;
    for(i=1;i<=2*n;i++)if(!VIZ[i]){num=0;visit(i);}
    for(i=1;i<=n;i++)if(CC[i]==CC[i+n]){printf("-1\n");return;}
    VALC=LOW;GRDC=VIZ;
    for(i=1;i<=NC;i++){VALC[i]=-1;GRDC[i]=0;}
    for(i=1;i<=2*n;i++)
        for(p=Out[i];p;p=p->urm)
            if(CC[i]!=CC[p->vec])
                GRDC[CC[p->vec]]++;
    for(i=1;i<=NC;i++)
        if(!GRDC[i])
        {
            p=new nod;p->vec=i;p->urm=0;
            if(!S){S=E=p;}
            else {E->urm=p;E=p;}
        }
    while(S)
    {
        i=S->vec;cf=i;ct=CC[non(CT[i]->vec)];
        VALC[cf]=0;VALC[ct]=1;
        for(p=CT[cf];p;p=p->urm)
            for(q=Out[p->vec];q;q=q->urm)
                if(CC[q->vec]!=cf)
                {
                    GRDC[CC[q->vec]]--;
                    if(!GRDC[CC[q->vec]]&&VALC[CC[q->vec]]==-1)
                    {
                        r=new nod;r->vec=CC[q->vec];r->urm=0;E->urm=r;E=r;
                    }
                }
        p=S;S=S->urm;delete p;
    }
    VAL=DFN;
    for(i=1;i<=NC;i++)
        for(p=CT[i];p;p=p->urm)
            VAL[p->vec]=VALC[i];
    for(i=1;i<=n;i++)printf("%d ",VAL[i]);
    printf("\n");
}
void visit(int I)
{
    int J;
    nod *p;
    VIZ[I]=1;num++;DFN[I]=LOW[I]=num;
    p=new nod;p->vec=I;p->urm=S;S=p;
    for(p=Out[I];p;p=p->urm)
    {
        if(VIZ[p->vec]==2)continue;
        if(!VIZ[p->vec])visit(p->vec);
        LOW[I]=LOW[I]<LOW[p->vec]?LOW[I]:LOW[p->vec];
    }
    if(DFN[I]==LOW[I])
    {
        NC++;
        for(;;)
        {
            J=S->vec;
            p=S;S=S->urm;delete p;
            p=new nod;p->vec=J;p->urm=CT[NC];CT[NC]=p;
            CC[J]=NC;VIZ[J]=2;
            if(J==I)break;
        }
    }
}