Cod sursa(job #790144)

Utilizator visanrVisan Radu visanr Data 20 septembrie 2012 15:59:56
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.39 kb
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;


#define nmax 200010
#define pb push_back

vector<int> G1[nmax], G2[nmax], Now, Top;
vector<vector<int> > V;
int ans[nmax], indCtc[nmax], N, M, X, Y;
bool Used[nmax];


int Get(int X)
{
    if(X > 0) return X;
    return abs(X) + N;
}

int Opp(int X)
{
    if(X <= N) return X + N;
    else return X - N;
}

void DFS1(int node)
{
     Used[node] = 1;
     for(vector<int> :: iterator it = G1[node].begin(); it != G1[node].end(); ++it)
         if(!Used[*it])
             DFS1(*it);
     Top.pb(node);
}

void DFS2(int node, int comp)
{
     indCtc[node] = comp;
     Now.pb(node);
     for(vector<int> :: iterator it = G2[node].begin(); it != G2[node].end(); ++it)
          if(!indCtc[*it])
               DFS2(*it, comp);
}

void Kosaraju()
{
     for(int i = 1; i <= 2 * N; i++)
             if(!Used[i])
                         DFS1(i);
     int cnt = 1;
     while(Top.size())
     {
                      if(!indCtc[Top.back()])
                      {
                              Now.clear();
                              DFS2(Top.back(), cnt);
                              cnt ++;
                              V.pb(Now);
                      }
                      Top.pop_back();
     }
}

int main()
{
    freopen("2sat.in", "r", stdin);
    freopen("2sat.out", "w", stdout);
    int i, j;
    scanf("%i %i", &N, &M);
    for(i = 1; i <= M; i++)
    {
          scanf("%i %i", &X, &Y);
          X = Get(X); Y = Get(Y);
          G1[Opp(X)].pb(Y); G1[Opp(Y)].pb(X);
          G2[X].pb(Opp(Y)), G2[Y].pb(Opp(X));
    }
    Kosaraju();
    bool ok = false;
    for(i = 1; i <= N && !ok; i++)
          if(indCtc[i] == indCtc[Opp(i)])
                       ok = true;
    if(!ok)
    {
           for(i = 0; i < V.size(); i++)
           {
                 if(!ans[i + 1]) ans[i + 1] = 2;
                 for(vector<int> :: iterator it = V[i].begin(); it != V[i].end(); ++it)
                                 if(!ans[indCtc[Opp(*it)]])
                                      ans[indCtc[Opp(*it)]] = 3 - ans[i + 1];
           }
           for(i = 1; i <= N; i++) 
                 if(ans[indCtc[i]] == 1) printf("1 ");
                 else printf("0 ");
    }else
    {
         printf("-1\n");
    }
    return 0;
}