Cod sursa(job #2857316)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 25 februarie 2022 12:43:10
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.85 kb
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
bool home = 1;

struct SAT{
        int temporal=0;
        int n;
        vector<vector<int>> g,ginv;
        vector<bool> vis;
        vector<int> order;
        vector<int> when;

        SAT(int n) : n(n),g(2*n),ginv(2*n),vis(2*n,0),when(2*n) {
                assert(n>0);
        }

        void addImplication(int a,int b,int aneg,int bneg){
                assert(0<=a&&a<n);
                assert(0<=b&&b<n);
                assert(0<=aneg&&aneg<2);
                assert(0<=bneg&&bneg<2);
                g[2*a+aneg].push_back(2*b+bneg);
                g[2*b+1-bneg].push_back(2*a+1-aneg);
        }



        void dfs(int a){
                vis[a]=1;
                for(auto&b:g[a]){
                        if(!vis[b]) dfs(b);
                }
                order.push_back(a);
        }

        void place(int a){
                vis[a]=1;
                when[a]=temporal;
                for(auto&b:ginv[a]){
                        if(!vis[b]) place(b);
                }
        }



        vector<int> get(){
                /// CTC
                for(int i=0;i<2*n;i++){
                        if(!vis[i]){
                                dfs(i);
                        }
                }
                for(int i=0;i<2*n;i++){
                        for(auto&j:g[i]){
                                ginv[j].push_back(i);
                        }
                }
                for(int i=0;i<2*n;i++){
                        vis[i]=0;
                }
                reverse(order.begin(),order.end());
                for(auto&i:order){
                        if(!vis[i]){
                                temporal++;
                                place(i);
                        }
                }
                vector<int> sol;
                for(int i=0;i<n;i++){
                        int a=2*i,b=2*i+1;
                        if(when[a]==when[b]) return {};
                        sol.push_back(when[a]>when[b]);
                }
                return sol;
        }
};

int main(){
        freopen ("2sat.in","r",stdin);
        freopen ("2sat.out","w",stdout);
        int n,m;
        cin>>n>>m;
        SAT sat(n);

        for(int i=1;i<=m;i++){
                int a,b,nega=0,negb=0;
                cin>>a>>b;
                if(a<0) a*=-1, nega=1;
                if(b<0) b*=-1, negb=1;
                a--;
                b--;
                nega^=1;
                sat.addImplication(a,b,nega,negb);
        }
        vector<int> sol=sat.get();
        if(sol.empty()){
                cout<<"-1\n";
        }else{
                for(auto&x:sol){
                        cout<<x<<" ";
                }
                cout<<"\n";
        }
        return 0;
}