2016 ACM-ICPC Asia Regional E – Similarity of Subtrees(dfs+hash)

E – Similarity of Subtrees

題意:輸入一棵由n個點和n-1條邊構成的樹,求這個樹中兩棵相似的子樹有多少對? 相似的子樹:要求在相同的深度,兩顆子樹的在這一層的節點數相同。


思路:利用樹的多項式做hash運算,然後同hash的統計即可;


代碼:

#include <bits/stdc++.h>
using namespace std;

#define ULL unsigned long long
#define LL long long

const ULL b=1e9+7;
const LL max_n=1e6+10;


map<ULL,LL> mp;
vector<int> g[max_n];

ULL d[max_n];
LL ans;
int n;

void dfs(int u,int fa){
    d[u]=1;
    for(int i=0;i<g[u].size();++i)
	{
        int v=g[u][i];
        if(v==fa)continue;
        dfs(v,u);
        d[u]+=d[v]*b;
    }
    mp[d[u]]++;
}

int main()
{
    while(scanf("%d",&n))
    {
    	for(int i=0; i<=n; i++)
            g[i].clear();
        mp.clear();
        ans=0;
        for(int i=1;i<n;i++)
		{
            int u,v;
			scanf("%d%d",&u,&v);
            g[u].push_back(v);
			g[v].push_back(u);
        }
        dfs(1,-1);
        for(map<ULL,LL>::iterator it=mp.begin(); it!=mp.end(); it++)
            ans+=it->second*(it->second-1LL)/2LL;
        cout<<ans<<endl;
    }
    return 0; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章