传送门

密码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}... xbasedx+ybasedy...

判断一下就好了

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;	
	}	
}