Cod sursa(job #390772)

Utilizator freak93Adrian Budau freak93 Data 4 februarie 2010 15:24:21
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.79 kb
#include<fstream>
#include<vector>
#include<cstring>
#include<queue>

using namespace std;

const char iname[]="2sat.in";
const char oname[]="2sat.out";
const int maxn=200005;

ifstream f(iname);
ofstream g(oname);

vector<int> E[maxn],S,aux;
vector<vector<int> > CTC;

queue<int> Q;

int n,i,j,m,lowlink[maxn],burst[maxn],burstt,value[maxn];
int x,y,inS[maxn],node,scc[maxn],inG[maxn];

int id(const int& x),deny(const int& y);
void tarjan(int x),build_grades();

int main()
{
    f>>n>>m;
    for(i=1;i<=m;++i)
    {
        f>>x>>y;
        x=deny(x);
        y=id(y);
        E[x].push_back(y);
        x=deny(x);
        y=deny(y);
        E[y].push_back(x);
    }
    for(i=n<<1;i;--i)
        if(burst[i]==0)
            tarjan(i);

    for(i=1;i<=n;++i)
        if(scc[i]==scc[i+n])
        {
            g<<-1<<"\n";
            f.close();
            g.close();

            return 0;
        }

    build_grades();
    for(i=0;i<CTC.size();++i)
        if(inG[i]==0)
            Q.push(i);
    memset(value,-1,sizeof(value));

    while(!Q.empty())
    {
        x=Q.front();
        Q.pop();
        for(vector<int>::iterator it=CTC[x].begin();it!=CTC[x].end();++it)
            for(vector<int>::iterator jt=E[*it].begin();jt!=E[*it].end();++jt)
                if(scc[*it]!=scc[*jt])
                {
                    --inG[scc[*jt]];
                    if(inG[scc[*jt]]==0)
                        Q.push(scc[*jt]);
                }

        for(vector<int>::iterator it=CTC[x].begin();it!=CTC[x].end();++it)
            if(value[*it]==-1)
                if(*it>n)
                    value[*it]=0,value[*it-n]=1;
                else
                    value[*it]=0,value[*it+n]=1;
    }
    for(i=1;i<=n;++i)
        g<<value[i]<<" ";
    g<<"\n";

}

void build_grades()
{
    for(int i=n<<1;i;--i)
        for(vector<int>::iterator it=E[i].begin();it!=E[i].end();++it)
            if(scc[*it]!=scc[i])
                ++inG[scc[*it]];
}

void tarjan(int x)
{
    lowlink[x]=burst[x]=++burstt;
    S.push_back(x);inS[x]=1;
    for(vector<int>::iterator it=E[x].begin();it!=E[x].end();++it)
        if(burst[*it]==0)
            tarjan(*it),
            lowlink[x]=min(lowlink[x],lowlink[*it]);
        else
            if(inS[*it])
                lowlink[x]=min(lowlink[x],lowlink[*it]);
    if(lowlink[x]==burst[x])
    {
        aux.clear();
        do
        {
            aux.push_back(node=S.back());
            S.pop_back();inS[node]=0;scc[node]=CTC.size();
        } while(node!=x);
        CTC.push_back(aux);
    }
}

int deny(const int& x)
{
    if(x<0)
        return -x;
    if(x<=n)
        return x+n;
    return x-n;
}
int id(const int& x)
{
    if(x<0)
        return n-x;
    return x;
}