这道题目我只能勉强看懂,题解就不写了,下面的博客写的很好。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL MAX_N = 200005;
vector<LL> G[MAX_N];
LL col[MAX_N];
LL vis[MAX_N];
LL siz[MAX_N];
LL sum[MAX_N];
LL ans;
void dfs(LL u, LL fa)
{
siz[u] = 1;
LL all = 0;
for (unsigned i = 0; i < G[u].size(); i++)
{
LL v = G[u][i];
if (v == fa)
continue;
LL pre = sum[col[u]];
dfs(v, u);
LL add = sum[col[u]] - pre;
LL tmp = siz[v] - add;
ans -= tmp * (tmp - 1) / 2;
all += add;
siz[u] += siz[v];
}
sum[col[u]] += siz[u] - all;
}
int main()
{
//freopen("test.txt", "r", stdin);
cin.sync_with_stdio(false);
LL n;
LL Case = 1;
while (cin >> n)
{
memset(col, 0, sizeof(col));
memset(vis, 0, sizeof(vis));
memset(siz, 0, sizeof(siz));
memset(sum, 0, sizeof(sum));
LL cnt = 0;
for (LL i = 1; i <= n; i++)
{
cin >> col[i];
if (!vis[col[i]])
{
cnt++;
vis[col[i]] = 1;
}
G[i].clear();
}
for (LL i = 1; i < n; i++)
{
LL u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
ans = cnt * n * (n - 1) / 2;
dfs(1, 0);
for (LL i = 1; i <= n; i++)
{
if (!vis[i])
continue;
ans -= (n - sum[i]) * (n - sum[i] - 1) / 2;
}
cout << "Case #" << Case++ << ": " << ans << endl;
}
return 0;
}