Cod sursa(job #1536630)

Utilizator hrazvanHarsan Razvan hrazvan Data 26 noiembrie 2015 14:25:39
Problema Obiective Scor 5
Compilator c Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <stdio.h>
#define MAXN 32000
#define MAXM 64000
#define MAXLG 15
#define INF 2000000000
int ult[MAXN], nod[MAXM], next[MAXM];
int ult2[MAXN], nod2[MAXM], next2[MAXM];
int v[MAXN], dv = 0, comp[MAXN];
int nivel[MAXN + 1], ret[MAXLG][MAXN], str[MAXLG][MAXN];
char viz[MAXN];
int col;

void dfs1(int x){
  viz[x] = 1;
  int poz = ult[x];
  while(poz != -1){
    if(!viz[nod[poz]])
      dfs1(nod[poz]);
    poz = next[poz];
  }
  v[dv] = x;
  dv++;
}

void dfs2(int x){
  viz[x] = 1;
  comp[x] = col;
  int poz = ult[x];
  while(poz != -1){
    if(!viz[nod[poz]])
      dfs2(nod[poz]);
    poz = next[poz];
  }
}

void dfs3(int x, int nv){
  viz[x] = 1;
  nivel[x] = nv;
  int poz = ult2[x];
  while(poz != -1){
    if(nivel[ret[0][nod2[poz]]] > nv)
      ret[0][nod2[poz]] = x;
    poz = next2[poz];
  }
  poz = ult2[x];
  while(poz != -1){
    if(!viz[nod2[poz]]){
      str[0][nod2[poz]] = x;
      dfs3(nod2[poz], nv + 1);
      if(nivel[ret[0][x]] > nivel[ret[0][nod2[x]]])
        ret[0][x] = ret[0][nod2[x]];
    }
    poz = next2[poz];
  }
}

inline void calcstram(int nr){
  int i, j;
  for(i = 1; i < MAXLG; i++){
    for(j = 0; j < nr; j++){
      if(ret[i - 1][j] != nr)
        ret[i][j] = ret[i - 1][ret[i - 1][j]];
      else
        ret[i][j] = nr;
      if(str[i - 1][j] != -1)
        str[i][j] = str[i - 1][str[i - 1][j]];
      else
        str[i][j] = -1;
    }
  }
}

inline int psolve(int x, int y){
  if(nivel[x] <= nivel[y])
    return 0;
  int i, rez = 0;
  for(i = MAXLG - 1; i >= 0; i--){
    if(nivel[ret[i][x]] != INF && nivel[ret[i][x]] > nivel[y]){
      x = ret[i][x];
      rez += (1 << i);
    }
  }
  return rez + 1;
}

inline int solve(int x, int y){
  int i, k = comp[x], l = comp[y], ck = k, cl = l;
  for(i = MAXLG - 1; i >= 0; i--){
    if(nivel[ck] - (1 << i) >= nivel[cl]){
      ck = str[i][ck];
    }
    if(nivel[cl] - (1 << i) >= nivel[ck]){
      cl = str[i][cl];
    }
  }
  for(i = MAXLG - 1; i >= 0; i--){
    if(str[i][ck] != str[i][cl]){
      ck = str[i][ck];
      cl = str[i][cl];
    }
  }
  if(ck != cl)
    ck = str[0][ck];
  return psolve(k, ck);
}

int main(){
  FILE *in = fopen("obiective.in", "r");
  int n, m, i, x, y, dr = 0;
  fscanf(in, "%d%d", &n, &m);
  for(i = 0; i < n; i++)
    ult[i] = -1;
  for(i = 0; i < m; i++){
    fscanf(in, "%d%d", &x, &y);
    x--;  y--;
    nod[dr] = y;
    next[dr] = ult[x];
    ult[x] = dr;
    dr++;
  }
  dfs1(0);
  memset(viz, 0, sizeof viz);
  int cmp = 0;
  for(i = 0; i < n; i++){
    if(!viz[v[i]]){
      col = cmp;
      cmp++;
      dfs2(v[i]);
    }
  }
  int poz;
  dr = 0;
  for(i = 0; i < cmp; i++)
    ult2[i] = -1;
  for(i = 0; i < n; i++){
    poz = ult[i];
    while(poz != -1){
      nod2[dr] = comp[nod[poz]];
      next2[dr] = ult2[comp[i]];
      ult2[comp[i]] = dr;
      dr++;
      poz = next[poz];
    }
  }
  memset(viz, 0, sizeof viz);
  int j;
  for(i = 0; i < MAXLG; i++){
    for(j = 0; j < MAXN; j++){
      ret[i][j] = cmp;
      str[i][j] = -1;
    }
  }
  nivel[cmp] = INF;
  dfs3(cmp - 1, 0);
  ret[0][cmp - 1] = cmp;
  calcstram(cmp);
  FILE *out = fopen("obiective.out", "w");
  int k;
  fscanf(in, "%d", &k);
  for(i = 0; i < k; i++){
    fscanf(in, "%d%d", &x, &y);
    fprintf(out, "%d\n", solve(x - 1, y - 1));
  }
  fclose(in);
  fclose(out);
  return 0;
}