Cod sursa(job #1141990)

Utilizator manutrutaEmanuel Truta manutruta Data 13 martie 2014 13:00:43
Problema 2SAT Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.93 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <bitset>
#include <vector>
#include <set>

using namespace std;
typedef vector<int>::iterator iter;
typedef vector<int>::reverse_iterator riter;
typedef set<int>::iterator siter;

#define MAXN 200005

ifstream f("2sat.in");
ofstream g("2sat.out");

int n, m;
vector<int> G[MAXN], Gt[MAXN], order;
bitset<MAXN> viz;
int comp[MAXN], compk = 1;
vector<int> comps[MAXN];
set<int> Gn[MAXN];
int sol[MAXN];

int toNode(int nd)
{
    if (nd < 0) {
        return n - nd;
    }
    return nd;
}

void topo(int nd)
{
    if (viz[nd] == true) {
        return;
    }
    viz[nd] = true;

    for (iter it = G[nd].begin(); it != G[nd].end(); it++) {
        topo(*it);
    }

    order.push_back(nd);
}

void connex(int nd)
{
    if (viz[nd] == true) {
        return;
    }
    viz[nd] = true;

    for (iter it = Gt[nd].begin(); it != Gt[nd].end(); it++) {
        connex(*it);
    }
    comp[nd] = compk;
    comps[compk].push_back(nd);
}

void createGN(int nd)
{
    for (iter it = G[nd].begin(); it != G[nd].end(); it++) {
        if (comp[nd] == comp[*it]) {
            continue;
        }

        Gn[comp[nd]].insert(comp[*it]);
    }
}

void topo2(int nd)
{
    if (viz[nd] == true) {
        return;
    }
    viz[nd] = true;

    for (siter it = Gn[nd].begin(); it != Gn[nd].end(); it++) {
        topo2(*it);
    }
    order.push_back(nd);
}

int backNd(int nd)
{
    if (nd > n) {
        return nd - n;
    }
    return nd;
}

int computeSol(int nd)
{
    if (nd > n) {
        return 1;
    }
    return 0;
}

int main()
{
    f >> n >> m;
    for (int i = 1; i <= m; i++) {
        int x, y;
        f >> x >> y;

        int xx = toNode(-x);
        int yy = toNode(y);
        G[xx].push_back(yy);
        Gt[yy].push_back(xx);

        yy = toNode(-y);
        xx = toNode(x);
        G[yy].push_back(xx);
        Gt[xx].push_back(yy);
    }

    for (int i = 1; i <= 2 * n; i++) {
        topo(i);
    }

    viz.reset();
    for (riter it = order.rbegin(); it != order.rend(); it++) {
        if (viz[*it] == false) {
            connex(*it); compk++;
        }
    }
    compk--;

    for (int i = 1; i <= 2 * n; i++) {
        createGN(i);
    }

    viz.reset();
    order.clear();
    for (int i = 1; i <= compk; i++) {
        topo2(i);
    }

    reverse(order.begin(), order.end());
    viz.reset();
    for (int i = 0; i < order.size(); i++) {
        for (iter it = comps[order[i]].begin(); it != comps[order[i]].end(); it++) {
            int nd = backNd(*it);
            if (viz[nd] == true) {
                break;
            }
            viz[nd] = true;

            sol[nd] = computeSol(*it);
        }
    }

    for (int i = 1; i <= n; i++) {
        g << sol[i] << ' ';
    }
    g << endl;

    f.close();
    g.close();
    return 0;
}