Nu aveti permisiuni pentru a descarca fisierul grader_test7.ok
Cod sursa(job #1709632)
Utilizator | 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;
}