Cod sursa(job #1902627)

Utilizator gabib97Gabriel Boroghina gabib97 Data 4 martie 2017 18:19:46
Problema Revolta Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.47 kb
#include <bits/stdc++.h>

#define N 100005
using namespace std;
int n, i, t, h[N], st, dr, l, g[N], T[N], r[N];
bool o[N], f[N];
vector<int> G[N];
vector<int> diam;

void DFS_diam(int s) {
    int m1, m2, a, b;
    m1 = m2 = 0;
    h[s] = 1;
    g[s] = s;
    for (auto x:G[s])
        if (!h[x]) {
            DFS_diam(x);
            if (h[x] + 1 > h[s])
                h[s] = h[x] + 1, g[s] = g[x]; //max depth
            if (h[x] > m1) {
                m2 = m1;
                m1 = h[x];
                b = a;
                a = g[x];
            } else if (h[x] > m2) m2 = h[x], b = g[x];
        }
    if (m2) {
        if (l < m1 + m2 + 1) {
            l = m1 + m2 + 1;
            st = a;
            dr = b;
        }
    } else {
        if (l < m1 + 1) {
            l = m1 + 1;
            st = s;
            dr = a;
        }
    }
}

void DFS(int s) {
    o[s] = 1;
    for (auto x:G[s])
        if (!o[x]) {
            T[x] = s;
            DFS(x);
        }
}

void det_max_depth(int s) {
    o[s] = 0;
    h[s] = 1;
    for (auto x:G[s])
        if (o[x]) {
            det_max_depth(x);
            if (!f[x] && h[s] < h[x] + 1)
                h[s] = h[x] + 1;
        }
}

int main() {
    freopen("revolta.in", "r", stdin);
    freopen("revolta.out", "w", stdout);
    int x, y;
    scanf("%d", &t);
    while (t--) {
        scanf("%i", &n);
        l = 0;
        for (i = 1; i <= n; i++) G[i].clear();
        memset(h, 0, (n + 1) * sizeof(int));
        for (i = 1; i < n; i++) {
            scanf("%i%i", &x, &y);
            G[x + 1].push_back(y + 1);
            G[y + 1].push_back(x + 1);
        }

        DFS_diam(1);
        memset(o, 0, (n + 1) * sizeof(bool));
        memset(f, 0, (n + 1) * sizeof(bool));
        DFS(st);
        diam.clear();
        for (i = dr; i != st; i = T[i]) //construct diam
            diam.push_back(i), f[i] = 1; //on diam
        diam.push_back(st);
        f[st] = 1;

        det_max_depth(st);

        r[0] = 1;
        for (i = 1; i < diam.size(); i++)
            r[i] = max(r[i - 1], i + h[diam[i]]);

        int d1, d2, j, sol;
        sol = INT_MAX;
        l = 0;
        for (i = diam.size() - 1, j = 0; i > 0; i--, j++) {
            l = max(l, j + h[diam[i]]);
            d1 = l - 1;
            d2 = r[i - 1] - 1;
            if (d1 > d2) swap(d1, d2);
            if ((d1 + 1) / 2 + 1 > d2 / 2) sol = min(sol, (d2 + 1) / 2 + (d1 + 1) / 2 + 1);
            else sol = min(sol, d2);
        }
        printf("%i\n", sol);
    }
    return 0;
}