Cod sursa(job #611386)

Utilizator proflaurianPanaete Adrian proflaurian Data 1 septembrie 2011 12:55:19
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include<cstdio>
#include<vector>
#include<deque>
#define N 200010
using namespace std;
vector<int> v[N],C[N];
deque<int> Q;
int n,m,i,x,y,cnt,Not[N],viz[N],c[N],Lo[N],Hi[N];
void Viz(int);
int main()
{
    freopen("2sat.in","r",stdin);
    freopen("2sat.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++){Not[i]=n+i;Not[n+i]=i;}
    for(;m;m--)
    {
        scanf("%d%d",&x,&y);
        x=x>0?x:n-x;y=y>0?y:n-y;
        v[Not[x]].push_back(y);
        v[Not[y]].push_back(x);
    }
    m=2*n;
    for(i=1;i<=m;i++)if(!c[i]){x=0;Viz(i);}
    for(i=1;i<=n;i++)if(c[i]==c[Not[i]]){printf("-1\n");return 0;}
    for(i=0;i<=cnt;i++){Lo[i]=-1;Hi[i]=0;}
    vector<int>::iterator it,IT;
    for(i=1;i<=m;i++)
        for(it=v[i].begin();it!=v[i].end();it++)
        {
            if(c[i]==c[*it])continue;Hi[c[*it]]++;
        }
    Q.resize(0);
    for(i=1;i<=cnt;i++)if(!Hi[i])Q.push_back(i);
    int TRUE,FALSE,True,False;
    for(;Q.size();)
    {
        FALSE=Q.front();Q.pop_front();
        False=C[FALSE][0];
        True=Not[False];
        TRUE=c[True];
        Lo[TRUE]=1;Lo[FALSE]=0;
        for(it=C[FALSE].begin();it!=C[FALSE].end();it++)
            for(IT=v[*it].begin();IT!=v[*it].end();IT++)
            {
                if(c[*it]==c[*IT])continue;
                Hi[c[*IT]]--;
                if(Hi[c[*IT]])continue;
                if(Lo[c[*IT]]>=0)continue;
                Q.push_back(c[*IT]);
            }
    }
    for(i=1;i<=n;i++)printf("%d ",Lo[c[i]]);
    return 0;
}
void Viz(int nod)
{
    int Nod;
    viz[nod]=1;Lo[nod]=Hi[nod]=++x;
    Q.push_back(nod);
    for(vector<int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
    {
        if(c[*it])continue;
        if(!viz[*it])Viz(*it);
        Lo[nod]=min(Lo[nod],Lo[*it]);
    }
    if(Hi[nod]==Lo[nod])
    {
        cnt++;
        for(;;)
        {
            Nod=Q.back();Q.pop_back();
            C[cnt].push_back(Nod);
            c[Nod]=cnt;
            if(Nod==nod)
                break;
        }
    }
}