密码boynextdoor
每颗子树设有 x x x个深度为 d x d_x dx, y y y个深度为 d y d_y dy…
那么可以哈希成 x ∗ b a s e d x + y ∗ b a s e d y . . . x*base^{d_x}+y*base^{d_y}... x∗basedx+y∗basedy...
判断一下就好了
把 b a s e base base适当放大可以减小冲突率
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ULL unsigned long long
const int maxn = 3e6+10;
const ULL base = 1e7+1;
map<ULL,int>mp;
struct edge{
int to,nxt;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v){ d[++cnt] = (edge){v,head[u]},head[u] = cnt; }
int res,n;
ULL dfs(int u)
{
ULL ans = 1;
for(int i=head[u];i;i=d[i].nxt )
{
int v = d[i].to;
ans += base*dfs(v);
}
res += mp[ans]; mp[ans]++;
return ans;
}
signed main()
{
while( scanf("%lld",&n)!=-1 )
{
for(int i=1;i<n;i++)
{
int l,r; scanf("%lld%lld",&l,&r);
add(l,r);
}
dfs(1);
cout << res << endl;
cnt = 1;
for(int i=1;i<=n;i++) head[i] = 0;
}
}