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 73 74 75 76 77 78 79
| #include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int Maxn = 2e5 + 10; int Head[Maxn], E[Maxn << 1], Next[Maxn << 1]; int N, U, V, Tot, Cur, C[Maxn]; bool Vis[Maxn]; ll Sum[Maxn], Size[Maxn]; ll Res;
inline void AddEdge(int U, int V) { Next[++Cur] = Head[U]; Head[U] = Cur; E[Cur] = V; }
void DFS(int U, int _F) { Size[U] = 1; ll X = Sum[C[U]], Y = X; for (int i = Head[U]; i; i = Next[i]) { int V = E[i]; if (V == _F) continue; DFS (V, U); Size[U] += Size[V]; ll Temp = Size[V] - Sum[C[U]] + X; Res += (Temp - 1) * Temp / 2; X = Sum[C[U]]; } Sum[C[U]] += Size[U] - (Sum[C[U]] - Y); }
inline void Init() { memset (Head, 0, sizeof Head); memset (Sum, 0, sizeof Sum); memset (Vis, 0, sizeof Vis); Tot = Res = Cur = 0; }
int main() { int Case(0); while (scanf ("%d", &N) != EOF) { Init(); int Cnt(0);
for (int i = 1; i <= N; ++i) { scanf ("%d", C + i); if (!Vis[C[i]]) ++Cnt, Vis[C[i]] = 1; }
for (int i = 1; i < N; ++i) { scanf ("%d %d", &U, &V); AddEdge(U, V), AddEdge(V, U); }
DFS(1, 0);
ll Ans = 1ll * N * (N - 1) * Cnt / 2;
for (int i = 1; i <= N; ++i) if (Vis[i]) { ll Temp = N - Sum[i]; Ans -= Temp * (Temp - 1) / 2; } printf ("Case #%d: %lld\n", ++Case, Ans - Res); } system("pause"); }
|