Cod sursa(job #1610843)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 23 februarie 2016 19:27:10
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const int knmax = 100005;
const int kn = 2 * 100005 + 70;

int n, m;
vector<int> graph[kn];

int neg(int x){ //we have negated terms from 1 to 100k
    if(x < knmax)
        return knmax + (knmax - x);
    return knmax - (x - knmax);
}

void read() {
    ifstream in("2sat.in");

    in >> n >> m;

    int x, y;
    for(int i = 1; i <= m; ++i) {
        in >> x >> y;
        x += knmax;
        y += knmax;
        graph[neg(x)].push_back(y); // not x implies y
        graph[neg(y)].push_back(x); // not y implies x
    }
}

vector<vector<int> > ssc;
bool vis[kn], instk[kn];
int index;
int dp[kn], ind[kn], sscnum[kn];
vector<int> stk;

void dfs(int x) {
    vis[x] = true;
    ind[x] = index;
    dp[x] = index;
    ++index;
    stk.push_back(x);
    instk[x] = true;

    for(int i = 0; i < graph[x].size(); ++i)
        if(!vis[graph[x][i]]) {
            dfs(graph[x][i]);
            dp[x] = min(dp[x], dp[graph[x][i]]);
        } else if (instk[graph[x][i]])
            dp[x] = min(dp[x], ind[graph[x][i]]);

    if(ind[x] == dp[x]) {
        vector<int> add;
        while(stk.back() != x){
            add.push_back(stk.back());
            instk[stk.back()] = false;
            sscnum[stk.back()] = ssc.size();
            stk.pop_back();
        }
        add.push_back(stk.back());
        instk[stk.back()] = false;
        sscnum[stk.back()] = ssc.size();
        stk.pop_back();

        ssc.push_back(add);
    }
}

bool impossible;
int tval[kn];
bool vis2[kn];

void dfs2(int x, int v) {
    vis2[x] = true;
    tval[x] = v;
    if(v == 1){
        if(!vis2[neg(x)])
            dfs2(neg(x), 2);
        else if(tval[neg(x)] != 2)
            impossible = true;
    }
    else
        if(!vis2[neg(x)])
            dfs2(neg(x), 1);
        else if(tval[neg(x)] != 1)
            impossible = true;

    for(int i = 0; i < graph[x].size(); ++i)
        if(!vis2[graph[x][i]])
            dfs2(graph[x][i], v);
}

void solve() {
    for(int i = 1 + knmax; i <= n + knmax; ++i){
        if(!vis[i])
            dfs(i);
        if(!vis[neg(i)])
            dfs(neg(i));
    }

    for(int i = 1 + knmax; i <= n + knmax; ++i)
        if(sscnum[i] == sscnum[neg(i)]){
            impossible = true;
            return;
        }

    for(int i = ssc.size() - 1; i >= 0; --i)
        if(!vis2[ssc[i][0]])
            dfs2(ssc[i][0], 1);

}

void write() {
    ofstream out("2sat.out");

    /*out << ssc.size() << "\n";
    for(int i = 0; i < ssc.size(); ++i){
        for(int j = 0; j < ssc[i].size(); ++j)
            out << ssc[i][j] << " ";
        out << "\n";
    }*/

    if(impossible){
        out << "-1\n";
        return;
    }

    for(int i = 1 + knmax; i <= n + knmax; ++i)
        if(tval[i] == 1)
            out << "0 ";
        else
            out << "1 ";
}

int main (){
    read();
    solve();
    write();

    return 0;
}