質問の意味:あなたは木のnドットを与えるために、それぞれが[1、n]はランダムな重みをドット、回文文字列があるどのように多くの木々をお願いします。
思考:ランダム重みは[1、N]です。大胆な推測回文文字列の長さの確率は非常に短くなければならないことを検討してください。リスト上の番号3に等しい未満で暴力の長さ。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> q[100005];
int a[100005];
int vis[100005];ll ans=0;
void dfs(int u,int fa)
{
vis[a[u]]++;
for(int i=0;i<q[u].size();i++)
{
int v=q[u][i];
if(v==fa) continue;
ans+=vis[a[v]];
vis[a[v]]++;
if(fa!=-1&&a[v]==a[fa]) ans++;
}
for(int i=0;i<q[u].size();i++)
{
int v=q[u][i];
if(v==fa) continue;
vis[a[v]]--;
}
vis[a[u]]--;
for(int i=0;i<q[u].size();i++)
{
int v=q[u][i];
if(v==fa) continue;
dfs(v,u);
}
}
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) q[i].clear();
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
memset(vis,0,sizeof(vis));
ans=0;
for(int i=0;i<n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);q[x].push_back(y);q[y].push_back(x);
}
dfs(1,-1);
printf("%d\n",ans+n);
}
return 0;
}