Cod sursa(job #654418)

Utilizator Smaug-Andrei C. Smaug- Data 30 decembrie 2011 14:29:12
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.18 kb
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

#define MAXN 200010

int I[MAXN], minI[MAXN], index, S[MAXN], inS[MAXN], t;
int scc_cnt, node_to_scc[MAXN], scc_in_deg[MAXN];
vector<int> G[MAXN], scc_G[MAXN], scc_list[MAXN];

inline int non(int x, int N){
  return (x > N)? x-N: x+N;
}

inline int rescale(int x, int N){
  return (x < 0)? -x+N: x;
}

void scc(int n){
  
  I[n]=minI[n]=++index;
  S[++t]=n; inS[n]=1;
  
  vector<int>::iterator ii;
  for(ii=G[n].begin(); ii!=G[n].end(); ii++){
    if(I[*ii] == -1){
      scc(*ii);
      minI[n]=min(minI[n], minI[*ii]);
    }
    else if(inS[*ii])
      minI[n]=min(minI[n], minI[*ii]);
  }

  if(I[n] == minI[n]){
    scc_cnt++;
    do {
      node_to_scc[S[t]]=scc_cnt;
      scc_list[scc_cnt].push_back(S[t]);
      inS[S[t]]=0;
    } while(S[t--] != n);
  }

}  

int main(){

  freopen("2sat.in", "r", stdin);
  freopen("2sat.out", "w", stdout);

  int N, M, i, a, b, l, r, n, impossible, aux;
  static int Q[MAXN], value[MAXN];
  vector<int>::iterator ii;

  scanf("%d%d", &N, &M);
  for(i=0; i<M; i++){
    scanf("%d%d", &a, &b);
    a=rescale(a, N); b=rescale(b, N);
    G[non(a, N)].push_back(b);
    G[non(b, N)].push_back(a);
  }

  for(i=1; i<=(N<<1); i++){
    I[i]=-1;
    value[i]=-1;
  }

  index=-1; t=-1;

  for(i=1; i<=(N<<1); i++)
    if(I[i] == -1)
      scc(i);

  impossible=0;
  for(i=1; i<=N; i++)
    if(node_to_scc[i] == node_to_scc[i+N])
      impossible=1;

  if(!impossible){
    for(i=1; i<=(N<<1); i++)
      for(ii=G[i].begin(); ii!=G[i].end(); ii++)
	if(node_to_scc[i] != node_to_scc[*ii]){
	  scc_G[node_to_scc[i]].push_back(node_to_scc[*ii]);
	  scc_in_deg[node_to_scc[*ii]]++;
	}
    
    r=-1;
    for(i=1; i<=scc_cnt; i++)
      if(scc_in_deg[i] == 0)
	Q[++r]=i;

    for(l=0; l<=r; l++){
      n=Q[l];
      for(ii=scc_list[n].begin(); ii!=scc_list[n].end(); ii++){
	aux=(*ii > N)? *ii-N: *ii;
	if(value[aux] == -1)
	  value[aux]=(*ii > N)? 1: 0;
      }
      for(ii=scc_G[n].begin(); ii!=scc_G[n].end(); ii++){
	scc_in_deg[*ii]--;
	if(scc_in_deg[*ii] == 0)
	  Q[++r]=*ii;
      }
    }

    for(i=1; i<=N; i++)
      printf("%d ", value[i]);
    printf("\n");

  }
  else
    printf("-1\n");

  return 0;

}