Similarity of Subtrees Aizu - 2784 哈希

Similarity of Subtrees

Define the depth of a node in a rooted tree by applying the following rules recursively:

The depth of a root node is 0.
The depths of child nodes whose parents are with depth d are d+1.
Let S(T,d) be the number of nodes of T with depth d. Two rooted trees T and T′ are similar if and only if S(T,d) equals S(T′,d) for all non-negative integer d.

You are given a rooted tree T with N nodes. The nodes of T are numbered from 1 to N. Node 1 is the root node of T. Let Ti be the rooted subtree of T whose root is node i. Your task is to write a program which calculates the number of pairs (i,j) such that Ti and Tj are similar and i<j.

Input
The input consists of a single test case.

N
a1 b1
a2 b2

aN−1 bN−1

The first line contains an integer N (1≤N≤100,000), which is the number of nodes in a tree. The following N−1 lines give information of branches: the i-th line of them contains ai and bi, which indicates that a node ai is a parent of a node bi. (1≤ai,bi≤N,ai≠bi) The root node is numbered by 1. It is guaranteed that a given graph is a rooted tree, i.e. there is exactly one parent for each node except the node 1, and the graph is connected.

Output
Print the number of the pairs (x,y) of the nodes such that the subtree with the root x and the subtree with the root y are similar and x<y.

Sample Input 1
5
1 2
1 3
1 4
1 5
Output for the Sample Input 1
6
Sample Input 2
6
1 2
2 3
3 4
1 5
5 6
Output for the Sample Input 2
2
Sample Input 3
13
1 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
6 10
7 11
8 12
11 13
Output for the Sample Input 3
14

题意:
给定一个根为1的树,问相似的树的对数是多少对?(相似的定义:要求在相同的深度,两棵子树的在这一层的节点数相同。)

分析:

![在这里插
举个栗子,如上图,各个结点的编号已经给出,Li表示当前的的深度

这个图就可以很好的解释这道题目的解题思路了先看左子树的2号点,2号点就可以表示为 2L3+2L4 ,然后7号可以表示为2L3+2L4
那么就可以得出,只要在dfs的过程中,他们的系数是相同的,那么就可以认为两个树相似了,那么剩下的就是判断是否得到的这个系数序列相同
这一题同样是处理相同字符子串的,感觉这个更简单,更直接https://blog.csdn.net/c___c18/article/details/100144266

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstring>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define rep(i,a,b) for(int i=a;i<=b;i++)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
vector<int>ve[N];
map<ull,ll>ma;
map<ull,ll>::iterator it;
ull base=131,ha[N];
void dfs(int now,int fa){
    ha[now]=1;
    for(int i=0;i<ve[now].size();i++){
        if(ve[now][i]==fa) continue;
        dfs(ve[now][i],now);
        ha[now]+=ha[ve[now][i]]*base;
    }
    ma[ha[now]]++;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++){int u,v;
        scanf("%d%d",&u,&v);
        ve[u].push_back(v);
        ve[v].push_back(u);
    }
    dfs(1,-1);
    ll ans=0;
    for(it=ma.begin();it!=ma.end();it++){
        ll num=(it->second);
        ans+=(num*(num-1))/2;
    }
    printf("%lld\n",ans);
    return 0;
}


发布了229 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/c___c18/article/details/100543865
今日推荐