Aizu

来源:互联网 发布:淘宝网热卖怎么加入 编辑:程序博客网 时间:2024/05/22 19:27

题意:

给你一棵树,问有多少对相似的子树(每层深度拥有相同数量的节点)。

思路:

将每棵树通过hash算法映射出一个值,下面这个公式用到了BKDRhash算法

Hash(T)= (n1+n2P+n3P2++nmPm1) % MOD /////////ni表示当前子树深度为i的节点有几个。

相当于将一棵树转化成一个p进制的整数。

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5+7;const ll p = 137;const ll mod = 1e9+7;int n;ll Hash[maxn];vector<int> arr[maxn];map<ll,ll> mp;map<ll,ll>::iterator it;void dfs(int u){    Hash[u] = 1;    int len = arr[u].size();    for(int i = 0;i<len;i++)    {        int v = arr[u][i];        dfs(v);        Hash[u] = (Hash[u]+Hash[v]*p)%mod;    }    mp[Hash[u]]++;}int main(){    scanf("%d",&n);    for(int i = 0;i<n-1;i++)    {        int u,v;        scanf("%d%d",&u,&v);        arr[u].push_back(v);    }    dfs(1);    ll ans = 0;    for(it = mp.begin();it!=mp.end();it++)    {        ans += (it->second-1)*it->second/2;    }    printf("%lld\n",ans);    return 0;}

原创粉丝点击