Cod sursa(job #1794021)

Utilizator TincaMateiTinca Matei TincaMatei Data 31 octombrie 2016 20:13:15
Problema Cerere Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <cstdio>
#include <ctype.h>

class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch() {
        ++sp;
        if (sp == 4096) {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (long long &n) {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};

const int MAX_N = 100000;
const int MAX_LOG = 18;
int up[1+MAX_N];
int d[1+MAX_LOG][1+MAX_N];
int dist[1+MAX_N];

int stramos(int nod, int level) {
  for(int i = 0; i < MAX_LOG; ++i)
    if((1 << i) & level)
      nod = d[i][nod];
  return nod;
}

int calcDist(int nod) {
  //printf("%d->%d;", nod, up[nod]);
  if(dist[nod] == -1) {
    if(up[nod] == 0)
      dist[nod] = 0;
    else
      dist[nod] = calcDist(up[nod]) + 1;
  }
  return dist[nod];
}

int main() {
  int n, a, b;
  InParser fin("cerere.in");
  fin >> n;
  for(int i = 1; i <= n; ++i)
    fin >> up[i];
  for(int i = 0; i < n - 1; ++i) {
    fin >> a >> b;
    d[0][b] = a;
  }
  for(int i = 1; i <= MAX_LOG; ++i)
    for(int j = 1; j <= n; ++j)
      d[i][j] = d[i - 1][d[i - 1][j]];

  for(int i = 1; i <= n; ++i) {
    if(up[i] > 0)
      up[i] = stramos(i, up[i]);
    dist[i] = -1;
  }

  FILE *fout = fopen("cerere.out", "w");

  for(int i = 1; i <= n; ++i)
    fprintf(fout, "%d ", calcDist(i));
  fclose(fout);
  return 0;
}