Cod sursa(job #1482621)

Utilizator thinkphpAdrian Statescu thinkphp Data 7 septembrie 2015 17:37:08
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <cstdio>
#include <vector>
#define FIN "2sat.in"
#define FOUT "2sat.out"

using namespace std;

class SAT2 {

public:
      SAT2(const int n = 0): N(n), 
                             t(0), 
                             G(vector<vector<int> >(2*n+1)), 
                             GT(vector<vector<int> >(2*n+1)),
                             visited(vector<bool>(2*n+1, false)),
                             postorder(vector<int>(2*n+1, 0)), 
                             solution(vector<bool>(2*n+1, false)){}

void addEdge(int x, int y) {

     if(x < 0) x = -x + N; 
     if(y < 0) y = -y + N;

     G[Not(x)].push_back(y); 
     GT[y].push_back(Not(x)); 

     G[Not(y)].push_back(x);  
     GT[x].push_back(Not(y));

}

int Not(int x) const {
 
    if(x > N) return  x - N;
        else  return  x + N;
}

void DFS(int node) {

     visited[ node ] = true;

     for(auto it : G[ node ])
    
         if(!visited[ it ]) {

            DFS( it ); 
         }

     postorder[ ++t ] = node;
};

void DFSR(int node) {

     visited[ node ] = false;

     solution[ Not(node) ] = true;

     for(auto it : GT[ node ]) {
    
         if(visited[ it ]) {

            DFSR( it ); 
         }
     }      
};

void Kosaraju() {

     for(int i = 1; i <= 2 * N; ++i ) {

         if(!visited[ i ]) {

            DFS( i );
         }
     }

     for(int i = 2 * N; i >= 1; --i ) {     

         int node = postorder[ i ];

         if( visited[ node ] && visited[ Not(node) ]) {

             DFSR( node );
         } 
     }
};

bool isSolution() const {

     for(int i = 1; i <= N; i++) {
  
         if(solution[ i ] && solution[ Not(i) ])  return false;
     }

    return true; 
}

public:
      int N, t;
      vector<vector<int> > G,GT;
      vector<bool> solution;
      vector<int> postorder;
      vector<bool> visited;
};

int main() {

    int n,
        m,
        x,
        y; 

    freopen(FIN, "r", stdin);

    //freopen(FOUT, "w", stdout);

    scanf("%d %d", &n, &m);

    SAT2 S(n);

     while(m--){ 

         scanf("%d %d", &x, &y);
         S.addEdge(x,y);
     }   

    S.Kosaraju();

    if( S.isSolution() ) {

      for(int i = 1; i <= S.N; i++) {

          printf("%d ", S.solution[ i ]); 
      }

     } else {

      printf("-1\n");
    }

    fclose( stdin ); 
    //fclose( stdout ); 

 return(0);
};