Cod sursa(job #2401884)

Utilizator georgerapeanuRapeanu George georgerapeanu Data 10 aprilie 2019 10:18:33
Problema 2SAT Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.68 kb
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

FILE *f = fopen("2sat.in","r");
FILE *g = fopen("2sat.out","w");

const int NMAX = 2e5;
const int OFFSET = NMAX + 3;
int n,m;

vector<int> graph[2 * OFFSET + 5];

bool viz[2 * OFFSET + 5];

bool inst[2 * OFFSET + 5];
int id[OFFSET + 5],last_id;
int low[2 * OFFSET + 5];
int st[2 * OFFSET + 5];
int len;
int last_ctc;
int ctc[2 * OFFSET + 5];
int ctc_val[2 * OFFSET + 5];
int ctc_gr[2 * OFFSET + 5];

vector<int> ctc_nodes[2 * OFFSET + 5];

void dfs(int nod,int tata){
    low[nod] = id[nod] = ++last_id;
    st[++len] = nod;inst[nod] = true;
    viz[nod] = true;

    for(auto it:graph[nod]){
        if(!viz[it]){
            dfs(it,nod);
        }

        if(inst[it] == true){
            low[nod] = min(low[it],low[nod]);
        }
    }

    if(low[nod] == id[nod]){
        last_ctc++;
        while(st[len] != nod){
            ctc[st[len]] = last_ctc;
            inst[st[len]] = false;
            ctc_nodes[last_ctc].push_back(st[len]);
            len--;
        }
        ctc[st[len]] = last_ctc;
        inst[st[len]] = false;
        ctc_nodes[last_ctc].push_back(st[len]);
        ctc_val[last_ctc] = -1;
        len--;
    }
}

bool in_topo[2 * OFFSET + 5];

int ans[2 * OFFSET + 5];

int main(){

    fscanf(f,"%d %d",&n,&m);

    for(int i = 1;i <= m;i++){
        int x,y;
        fscanf(f,"%d %d",&x,&y);
        graph[OFFSET - x].push_back(OFFSET + y);
        graph[OFFSET - y].push_back(OFFSET + x);
    }

    for(int nod = OFFSET - n;nod <= OFFSET + n;nod++){
        if(nod == OFFSET)continue;
        if(viz[nod] == false){
            dfs(nod,0);
        }
    }

    for(int nod = OFFSET - n;nod <= OFFSET + n;nod++){
            if(nod == OFFSET)continue;
        ctc_val[ctc[nod]] = -1;
        for(auto it:graph[nod]){
            if(ctc[nod] != ctc[it]){
                ctc_gr[ctc[it]]++;
            }
        }
    }

    vector<int> topo;

    for(int nod = OFFSET - n;nod <= OFFSET + n;nod++){
            if(nod == OFFSET)continue;
        if(ctc_gr[ctc[nod]] == 0 && in_topo[ctc[nod]] == false){
            topo.push_back(ctc[nod]);
            in_topo[ctc[nod]] = true;
        }
    }

    for(int i = 0;i < (int)topo.size();i++){
        int val = ctc_val[topo[i]];
        for(auto it:ctc_nodes[topo[i]]){
            if(ans[it] != -1){
                if(val == -1){
                    val = ans[it];
                }
                else if(val != ans[it]){
                    fprintf(g,"-1");
                    return 0;
                }
            }
        }

        if(val == -1){
            val = 0;
        }

        ctc_val[topo[i]] = val;

        for(auto it:ctc_nodes[topo[i]]){
            ans[it] = val;
            ans[2 * OFFSET - it] = (val ^ 1);
            for(auto it2:graph[it]){
                if(topo[i] != ctc[it2]){
                    ctc_gr[ctc[it2]]--;
                    if(ctc_gr[ctc[it2]] == 0 && in_topo[ctc[it2]] == false){
                        topo.push_back(ctc[it2]);
                        in_topo[ctc[it2]] = true;
                    }
                    if(val == 1){
                        ctc_val[ctc[it2]] = 1;
                    }
                }
            }
        }
    }

    for(int i = OFFSET - n;i <= OFFSET + n;i++){
            if(i == OFFSET)continue;
        if(ans[i] + ans[2 * OFFSET - i] != 1){
            fprintf(g,"-1");
            return 0;
        }
    }

    for(int i = OFFSET + 1;i <= OFFSET + n;i++){
            if(i == OFFSET)continue;
        fprintf(g,"%d ",ans[i]);
    }

    return 0;
}