Cod sursa(job #1709632)

Utilizator hrazvanHarsan Razvan hrazvan Data 28 mai 2016 13:08:46
Problema Revolta Scor 0
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 3.32 kb
#include <cstdio>
#include <cstring>
#define MAXN 100000
int ut[MAXN], nd[2 * MAXN], nxt[2 * MAXN], dr;
int v[MAXN], dv, nv[MAXN];
int d1[MAXN], d2[MAXN], c1[MAXN], c2[MAXN];
int dist[MAXN], prev[MAXN];
char pdiam[MAXN];

inline int min2(int x, int y){
  return x < y ? x : y;
}

inline int max2(int x, int y){
  return x > y ? x : y;
}

inline void invs(int *v, int dv){
  int i, aux, dv2 = dv / 2;
  for(i = 0; i <= dv2; i++){
    aux = v[i];  v[i] = v[dv - i - 1];  v[dv - i - 1] = aux;
  }
}

inline void add(int x, int y){
  nd[dr] = y;
  nxt[dr] = ut[x];
  ut[x] = dr;
  dr++;
}

void dfs1(int x){
  int poz = ut[x];
  while(poz != -1){
    if(dist[nd[poz]] == -1){
      dist[nd[poz]] = dist[x] + 1;
      dfs1(nd[poz]);
    }
    poz = nxt[poz];
  }
}

void dfs2(int x){
  int poz;
  poz = ut[x];
  while(poz != -1){
    if(dist[nd[poz]] == -1){
      dist[nd[poz]] = dist[x] + 1;
      prev[nd[poz]] = x;
      dfs2(nd[poz]);
    }
    poz = nxt[poz];
  }
}

int maxdfs(int x, int tata){
  int r = -1, poz;
  poz = ut[x];
  while(poz != -1){
    if(nd[poz] != tata)
      r = max2(r, maxdfs(nd[poz], x));
    poz = nxt[poz];
  }
  return r + 1;
}

inline void calcvdinnv(){
  int i, poz, mx, cx;
  for(i = 0; i < dv; i++){
    mx = 0;
    poz = ut[nv[i]];
    while(poz != -1){
      if(!pdiam[nd[poz]]){
        cx = maxdfs(nd[poz], nv[i]);
        if(cx + 1 > mx)
          mx = cx + 1;
      }
      poz = nxt[poz];
    }
    v[i] = mx;
  }
}


inline void aflv(int n){
  memset(dist, -1, sizeof dist);
  dist[0] = 0;
  dfs1(0);
  int i, mx = -1, p, p2;
  for(i = 0; i < n; i++){
    if(dist[i] > mx){
      mx = dist[i];
      p = i;
    }
  }
  dv = 0;
  memset(dist, -1, sizeof dist);
  dist[p] = 0;
  dfs2(p);
  mx = -1;
  for(i = 0; i < n; i++){
    if(dist[i] > mx){
      mx = dist[i];
      p2 = i;
    }
  }
  while(p2 != p){
    nv[dv] = p2;
    dv++;
    pdiam[p2] = 1;
    p2 = prev[p2];
  }
  nv[dv] = p;
  dv++;
  pdiam[p] = 1;
  invs(nv, dv);
  calcvdinnv();
}

inline void calc_diam(int *r){
  int mx = 0, diam = 0, i;
  for(i = 0; i < dv; i++){
    if(v[i] + mx > diam)
      diam = v[i] + mx;
    mx = max2(mx, v[i]) + 1;
    r[i] = diam;
  }
}

inline void calc_centr(int *r){
  int i, dr = 0, pc = 0, pdr = 0, m, mp;
  for(i = 0; i < dv; i++){
    if(i - pc + v[i] > dr){
      dr = i - pc + v[i];
      pdr = i;
    }
    if(dr > pc){
      m = max2(dr, pc);
      mp = max2(dr - 1, pc + 1);
      while(mp < m){
        pc++;
        dr--;
        m = mp;
        mp = max2(dr - 1, pc + 1);
      }
    }
    r[i] = max2(dr, pc);
  }
}

int main(){
  FILE *in = fopen("revolta.in", "r");
  FILE *out = fopen("revolta.out", "w");
  int t, n, a, b, i, rez;
  fscanf(in, "%d", &t);
  for(; t > 0; t--){
    fscanf(in, "%d", &n);
    memset(ut, -1, sizeof ut);
    dr = 0;
    for(i = 1; i < n; i++){
      fscanf(in, "%d%d", &a, &b);
      add(a, b);
      add(b, a);
    }
    aflv(n);
    calc_diam(d1);
    calc_centr(c1);
    invs(v, dv);
    calc_diam(d2);
    calc_centr(c2);
    rez = dv;
    for(i = 0; i < dv - 1; i++)
      rez = min2(rez, max2(max2(d1[i], d2[dv - i - 2]), c1[i] + c2[dv - i - 2] + 1));
    fprintf(out, "%d\n", rez);
  }
  fclose(in);
  fclose(out);
  return 0;
}