Cod sursa(job #994805)

Utilizator primulDarie Sergiu primul Data 6 septembrie 2013 13:20:21
Problema Andrei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 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];
//int scc_in_deg[MAXN]; replaced with inS... another puny one
vector<int> G[MAXN], scc_list[MAXN];
  
inline int non(int x, int N){
  return (x > N)? x-N: x+N;
}
  
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("andrei.in", "r", stdin);
  freopen("andrei.out", "w", stdout);
  
  int N, M, i, a, b, c, l, r, n, aux;
  //static int Q[MAXN], value[MAXN]; replaced with S and I to optimize memory consumption... puny
  vector<int>::iterator ii, jj;
  
  scanf("%d%d", &N, &M);
  for(i=0; i<M; i++){
    scanf("%d%d%d", &a, &b, &c);
     
    if(c==0){
      G[non(a, N)].push_back(b);
      G[non(b, N)].push_back(a);
    }
    else if(c==1){
      a=non(a, N);
      b=non(b, N);
      G[non(a, N)].push_back(b);
      G[non(b, N)].push_back(a);
    }
    else {
      a=non(a, N);
      G[non(a, N)].push_back(b);
      G[non(b, N)].push_back(a);
      a=non(a, N);
      b=non(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;
  }
  
  index=-1; t=-1;
  
  for(i=1; i<=(N<<1); i++)
    if(I[i] == -1)
      scc(i);
  
  for(i=1; i<=(N<<1); i++){
    I[i]=-1;
    inS[i]=0;
  }
  
  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]);
    inS[node_to_scc[*ii]]++;
      }
    
  r=-1;
  for(i=1; i<=scc_cnt; i++)
    if(inS[i] == 0)
      S[++r]=i;
    
  for(l=0; l<=r; l++){
    n=S[l];
    for(ii=scc_list[n].begin(); ii!=scc_list[n].end(); ii++){
      aux=(*ii > N)? *ii-N: *ii;
      if(I[aux] == -1)
    I[aux]=(*ii > N)? 1: 0;
    }
    for(ii=scc_list[n].begin(); ii!=scc_list[n].end(); ii++){
      for(jj=G[*ii].begin(); jj!=G[*ii].end(); jj++){
    if(node_to_scc[*ii] != node_to_scc[*jj]){
      inS[node_to_scc[*jj]]--;
      if(inS[node_to_scc[*jj]] == 0)
        S[++r]=node_to_scc[*jj];
    }
      }
    }
  }
    
  for(i=1; i<=N; i++)
    printf("%d ", I[i]);
  printf("\n");
  
  return 0;
  
}