Cod sursa(job #1535220)

Utilizator timicsIoana Tamas timics Data 24 noiembrie 2015 14:28:51
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include<stdio.h>
#include<vector>
#include<iostream>
using namespace std;
 
int M,x,y;
 
int N,s[210000],curr,c[210000],sol[210000];
vector<int> g[210000],gt[210000],v[210000];
bool viz[210000],vz[210000];
 
// 2*k is v[k], 2*k+1 is -v[k], 1 is false, 2 is true, m is normal graph, n is complementary
void dfs(int x) {
    viz[x] = 1;
    for(auto y: g[x]) {
        if(!viz[y]) dfs(y);
    }
    s[++curr] = x;
}
 
void dfs2(int x, int comp) {
    viz[x] = 0; c[x] = comp;
    v[comp].push_back(x);
    for(auto y: gt[x]) {
        if(viz[y]) dfs2(y,comp);
    }
}
 
inline int ng(int x) {
    if(x%2) return x-1; return x+1;
}
 
bool f(int x, int val) {
    vz[x] = 1;
    for(auto y: v[x]) {
        if(sol[y] && sol[y]!=val) return false;
        sol[y] = val;
    }
    for(auto y: v[x]) {
        y = ng(y);
        if(sol[y] && sol[y]!=3-val) return false;
        if(!sol[y]) return f(c[y],3-val);
    }
    return true;
}
 
bool sat() {
    int comp = 0;
    for(int i=2;i<=2*N+1;++i) {
        if(!viz[i]) dfs(i);
    }
    for(int i=curr;i>=1;--i) {
        if(viz[s[i]]) dfs2(s[i],++comp);
    }
    for(int i=1;i<=comp;++i) {
        if(!vz[i]) if(!f(i,1)) return false;
    }
    return true;
}

//s 0 normal, s 1 negation
void add_disj(int x, int sx, int y, int sy) {
    g[2*x+(1-sx)].push_back(2*y+sy);
    g[2*y+(1-sy)].push_back(2*x+sx);
    gt[2*y+sy].push_back(2*x+(1-sx));
    gt[2*x+sx].push_back(2*y+(1-sy));
}
 
int main() {
    freopen("2sat.in","r",stdin);
    freopen("2sat.out","w",stdout);
    scanf("%d%d",&N,&M);
    for(int i=0;i<M;++i) {
        scanf("%d%d",&x,&y);
        int a = 0, b = 0;
        if(x < 0) {
            a = 1;
            x = -x;
        }
        if(y < 0) {
            b = 1;
            y = -y;
        }
        add_disj(x,a,y,b);
    }
    if(!sat()) {
        printf("-1");
    } else {
        for(int i=1;i<=N;++i) {
            printf("%d ",sol[2*i]-1);
        }
    }
 
    return 0;
}