Cod sursa(job #2030892)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 2 octombrie 2017 14:14:30
Problema Trigame Scor 15
Compilator cpp Status done
Runda Simulare 31b Marime 1.72 kb
#include <cstdio>
#include <vector>
#include <algorithm>

#define shint short int

#define MAXN 2048

shint dp[MAXN + 1][MAXN + 1][2];
int h[MAXN + 1], hmax[MAXN + 1], t[MAXN + 1];
int l[MAXN + 1], r[MAXN + 1], e[MAXN + 1], k;
int a[MAXN + 1], b[MAXN + 2], st[MAXN + 1];
std::vector <int> g[MAXN + 1];

void dfs1(int x) {
    l[x] = ++k;
    hmax[x] = e[k] = h[x];
    for (auto &y : g[x]) if (y != t[x]) {
        t[y] = x;
        h[y] = h[x] + 1;
        dfs1(y);
        hmax[x] = std::max(hmax[x], hmax[y]);
    }
    r[x] = k;
}

inline shint calc(int x) {
    return std::max(a[l[x] - 1], b[r[x] + 1]);
}

void dfs2(int x) {
    for (auto &y: g[x]) if (y != t[x]) {
        st[h[y]] = y;
        dp[k][y][0] = calc(st[h[y] / 2 + 1]);
        dp[k][y][1] = calc(st[(h[y] - 1) / 2 + 1]);
        dfs2(y);
    }
}

int main() {
    FILE *fin = fopen("trigame.in", "r"), *fout = fopen("trigame.out", "w");

    int n;
    fscanf(fin, "%d", &n);

    for (int i = 1; i < n; i++) {
        int x, y;
        fscanf(fin, "%d%d", &x, &y);

        g[x].push_back(y);
        g[y].push_back(x);
    }

    for (int i = 1; i <= n; i++) {
        t[i] = 0;
        h[i] = 0;
        k = 0;
        dfs1(i);
        a[0] = 0;
        for (int j = 1; j <= n; j++)
            a[j] = std::max(a[j - 1], e[j]);
        b[n + 1] = 0;
        for (int j = n; j > 0; j--)
            b[j] = std::max(b[j + 1], e[j]);
        k = i;
        dfs2(i);
    }

    int ans = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            ans += bool(i != j && dp[i][j][0] > dp[j][i][1]);

    fprintf(fout, "%d\n", ans);

    fclose(fin);
    fclose(fout);
    return 0;
}