1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #include<cstdio> #include<cstring> #include<algorithm> #define RG register
inline int read() { int data = 0, w = 1; char ch = getchar(); while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if(ch == '-') w = -1, ch = getchar(); while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar(); return data * w; }
const int maxn(100010); struct edge { int next, to; } e[maxn << 1]; int head[maxn], e_num, n; inline void add_edge(int from, int to) { e[++e_num] = (edge) {head[from], to}; head[from] = e_num; }
int dep[maxn], heavy[maxn], maxdep[maxn]; void dfs(int x, int fa) { for(RG int i = head[x]; i; i = e[i].next) { int to = e[i].to; if(to == fa) continue; dfs(to, x); maxdep[x] = std::max(maxdep[x], maxdep[to]); if(maxdep[to] > maxdep[heavy[x]]) heavy[x] = to; } maxdep[x] = maxdep[heavy[x]] + 1; }
long long *f[maxn], *g[maxn], pool[maxn << 2], *id = pool, ans; void calc(int x, int fa) { if(heavy[x]) f[heavy[x]] = f[x] + 1, g[heavy[x]] = g[x] - 1, calc(heavy[x], x); f[x][0] = 1, ans += g[x][0]; for(RG int i = head[x]; i; i = e[i].next) { int to = e[i].to; if(to == fa || to == heavy[x]) continue; f[to] = id; id += maxdep[to] << 1; g[to] = id; id += maxdep[to] << 1; calc(to, x); for(RG int j = 0; j < maxdep[to]; j++) { if(j) ans += f[x][j - 1] * g[to][j]; ans += g[x][j + 1] * f[to][j]; } for(RG int j = 0; j < maxdep[to]; j++) { g[x][j + 1] += f[x][j + 1] * f[to][j]; if(j) g[x][j - 1] += g[to][j]; f[x][j + 1] += f[to][j]; } } }
int main() { n = read(); for(RG int i = 1, a, b; i < n; i++) a = read(), b = read(), add_edge(a, b), add_edge(b, a); dfs(1, 0); f[1] = id; id += maxdep[1] << 1; g[1] = id; id += maxdep[1] << 1; calc(1, 0); printf("%lld\n", ans); return 0; }
|