Cod sursa(job #789699)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 18 septembrie 2012 22:10:27
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <fstream>
#include <vector>
#include <queue>

#define MAX 262144
#define pb push_back

using namespace std;

vector<int> Go[MAX], Gi[MAX], discovered, part;
vector< vector < int > > v;
int where[MAX], value[MAX], n, m, a, b;
bool used[MAX];

inline int abs(int a)
{
    if(a > 0) return a;
    return -a;
}

inline int getNr(int a)
{
    if(a > 0) return a;
    else return abs(a) + n;
}

inline int getOpposite(int a)
{
    if(a <= n) return a + n;
    else return a - n;
}

void Citire()
{
    ifstream in("2sat.in");
    in>>n>>m;
    for(int i = 1; i <= m; i++)
    {
        in>>a>>b;
        a = getNr(a); b = getNr(b);
        Go[getOpposite(a)].pb(b);
        Go[getOpposite(b)].pb(a);
        Gi[a].pb(getOpposite(b));
        Gi[b].pb(getOpposite(a));
    }
    in.close();
}

void DFF(int nod)
{
    used[nod] = true;
    for(int i = 0; i < Go[nod].size(); i++)
        if(!used[Go[nod][i]])
            DFF(Go[nod][i]);
    discovered.pb(nod);
}

void DFS(int nod, int value)
{
    where[nod] = value;
    part.pb(nod);
    for(int i = 0; i < Gi[nod].size(); i++)
        if(!where[Gi[nod][i]])
            DFS(Gi[nod][i], value);
}

void Kosaraju()
{
    for(int i = 1; i <= 2 * n; i++)
        if(!used[i]) DFF(i);
    int contor = 1;
    for(; discovered.size(); discovered.pop_back())
        if(!where[discovered.back()])
        {
            part.clear();
            DFS(discovered.back(), contor++);
            v.pb(part);
        }
}

int Assign()
{
    for(int i = 1; i <= n; i++)
        if(where[i] == where[getOpposite(i)])
            return 0;
    for(int i = 0; i < v.size(); i++)
    {
        if(!value[i + 1])
            value[i + 1] = 2;
        for(int j = 0; j < v[i].size(); j++)
        {
            int nod = v[i][j];
            if(!value[where[getOpposite(nod)]])
                value[where[getOpposite(nod)]] = 3 - value[i + 1];
        }
    }
    return 1;
}

int main()
{
    Citire();
    Kosaraju();
    ofstream out("2sat.out");
    if(Assign())
    {
        for(int i = 1; i <= n; i++)
            out<<(value[where[i]] == 1 ? 1 : 0)<<" ";
    }
    else
        out<<"-1";
    return 0;
}