4292: Count the Trees(树hash)

4292: Count the Trees 

时间限制(普通/Java):2000MS/6000MS     内存限制:65536KByte
总提交: 15            测试通过:6

描述

A binary tree is a tree data structure in which each node has at most two child nodes, usually distinguished as "left" and "right". A subtree of a tree T is a tree consisting of a node in T and all of its descendants in T. Two binary trees are called identical if their left subtrees are the same(or both having no left subtree) and their right subtrees are the same(or both having no right subtrees).

According to a recent research, some people in the world are interested in counting the number of identical subtree pairs, each from the given trees respectively.

Now, you are given two trees. Write a program to help to count the number of identical subtree pairs, such that the first one comes from the first tree and the second one comes from the second tree.

输入

There are multiple test cases. The first line contains a positive integer T (T ≤ 20) indicating the number of test cases. Then T test cases follow.

In each test case, There are two integers n and m (1 ≤ n, m ≤ 100000) indicating the number of nodes in the given two trees. The following n lines describe the first tree. The i-th line contains two integers u and v (1 ≤ u ≤ n or u = -1, 1 ≤ v ≤ n or v = -1) indicating the indices of the left and right children of node i. If u or v equals to -1, it means that node i don‘t have the corresponding left or right child. Then followed by m lines describing the second tree in the same format. The roots of both trees are node 1.

输出

For each test case, print a line containing the result.

样例输入

2
2 2
-1 2
-1 -1
2 -1
-1 -1
5 5
2 3
4 5
-1 -1
-1 -1
-1 -1
2 3
4 5
-1 -1
-1 -1
-1 -1

样例输出

1
11

提示

The two trees in the first sample look like this.

解题思路: 求子树相等总共有多少个  树hash

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4
 5 int t;
 6 int n,m,jishu,flag;
 7 const int maxn=1e5+5;
 8 int tree[maxn][2];
 9 int num[maxn];
10 map<pair<int,int>,int>ma;
11 ll res;
12
13 int dfs(int ee){
14     int ls=-1,rs=-1,t;
15     if(tree[ee][0]!=-1) ls=dfs(tree[ee][0]);
16     if(tree[ee][1]!=-1) rs=dfs(tree[ee][1]);
17     if(!flag){
18         if(!ma.count({ls,rs})) ma[{ls,rs}]=++jishu;  //hash
19         num[t=ma[{ls,rs}]]++;  //计数
20     }
21     else{
22         if(ma.count({ls,rs})) res+=num[t=ma[{ls,rs}]];
23         else t=0;
24     }
25     return t;
26 }
27
28 int main(){
29     scanf("%d",&t);
30     while(t--){
31         ma.clear();
32         memset(num,0,sizeof(num));
33         scanf("%d%d",&n,&m);
34         for(int i=1;i<=n;i++){
35             scanf("%d%d",&tree[i][0],&tree[i][1]);
36         }
37         flag=0,jishu=0;
38         dfs(1);
39         for(int i=1;i<=m;i++){
40             scanf("%d%d",&tree[i][0],&tree[i][1]);
41         }
42         res=0,flag=1,dfs(1);
43         printf("%lld\n",res);
44     }
45     return 0;
46 }

原文地址:https://www.cnblogs.com/qq-1585047819/p/12078371.html

时间: 2024-10-14 05:31:16

4292: Count the Trees(树hash)的相关文章

ZOJ 3602 Count the Trees 树的同构 (哈希)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4705 题意:给出两棵二叉树A和B,问分别处于A中的子树a和处于B中的子树b结构相同的有多少对. 思路:哈希的想法,不同的数字对应的是不同的结构,比如1代表着单独的叶子结点,2代表着有左子树是叶子结点而没有右子树的子树...每出现一种新的子树情形就记录下来,记录的方式是用dfs回溯过程中判断左子树和右子树组成的子树是否出现过(用pair记录子树的情况,也就是左右子树,两个

UVa 10007 &amp; hdu 1131 Count the Trees (卡特兰数)

Count the Trees Time Limit:3000MS    Memory Limit:0KB     64bit IO Format:%lld & %llu SubmitStatus Description  Count the Trees  Another common social inability is known as ACM (Abnormally Compulsive Meditation). This psychological disorder is somewh

树Hash

我们有时需要判断一些树是否同构.这时,选择恰当的Hash方式来将树映射成一个便于储存的Hash值(一般是 32 位或 64 位整数)是一个优秀的方案. 树Hash定义在有根树上.判断无根树同构的时候,可以比较重心为根的Hash值或者比较每个点为根的Hash值. 树哈希有很多种哈希方式,下面介绍其中一种: $f_x$表示$x$为根的子树的Hash值,$son_x$表示$x$的儿子结点集合,$size_y$表示$y$为根的子树规模,$prime(i)$表示第$i$个素数,则 $$f_x = 1 +

zjuoj 3602 Count the Trees

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3602 Count the Trees Time Limit: 2 Seconds      Memory Limit: 65536 KB A binary tree is a tree data structure in which each node has at most two child nodes, usually distinguished as "left&

Count the Trees 典型卡特兰数

Count the Trees 题目分析:给你n个分别标为1,2,...,n的节点,问可以构成多少棵而叉树. 分析:首先考虑n个节点是相同的.任选一个节点做跟节点,那么剩下的n-1个节点构成跟节点的左子树和又子数. h[n] = h[0] * h[n-1] + h[1] * h[n - 2] + ... + h[n-1] * h[0];这正是卡特蓝表达式. h[n] = h[n-1] * (4 * n - 2) / (n + 1).   h[n] = C(2 * n,n)/(n + 1); 对于

Disharmony Trees 树状数组

Disharmony Trees Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description One day Sophia finds a very big square. There are n trees in the square. They are all so tall. Sophia is very interesting in them.

bzoj3162 独钓寒江雪 树Hash 树dp 组合数学

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3162 题意:给出一棵无根树,求出本质不同独立集数目. 这道题真是一道好题……无限$orz$ $VFleaKing$……对着题解看了半天才看明白明明是你太蒻了…… 好了不废话直接切入正题.首先我们需要找出一个方式使得所有的同构树形态都一样,怎么办呢,找到这个树的重心,以这个重心为根重新搞. 但是怎么搞出重心呢……首先,重心一定在整棵树最长的链上.那么我们先随意以一个点为起点广搜一次找到最远点,

POJ 2777 Count Color(线段树)

题目地址:POJ 2777 我去..延迟标记写错了.标记到了叶子节点上....这根本就没延迟嘛...怪不得一直TLE... 这题就是利用二进制来标记颜色的种类.然后利用或|这个符号来统计每个区间不同颜色种数. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h

POJ2777 Count Color 线段树区间更新

题目描述: 长度为L个单位的画板,有T种不同的颜料,现要求按序做O个操作,操作分两种: 1."C A B C",即将A到B之间的区域涂上颜色C 2."P A B",查询[A,B]区域内出现的颜色种类 出现操作2时,请输出答案 PS:初始状态下画板颜色为1 一开始没有想那么好,用int整型位移来代替颜色,还是使用了最传统的bool color[来记录,可是不知道错在了哪里, #include<iostream> #include<cstdio>