ZOJ - 3602 Count the Trees 二叉树同构

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.

Input

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 uor 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.

Output

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

Sample Input

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

Sample Output

1
11

       求a,b树中相同结构的二叉子树对数的数量。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int a[maxn][2], b[maxn][2];
int sum[maxn]; long long ans;
map<pair<int, int>, int>G;
int cnt = 1;
pair<int, int> makepair(int a, int b)
{
	pair<int, int> p;
	p.first = a;
	p.second = b;
	return p;
}

int dfs_a(int u) {
	int son1, son2;
	if (a[u][0] != -1)
		son1 = dfs_a(a[u][0]);
	else son1 = -1;

	if (a[u][1] != -1)
		son2 = dfs_a(a[u][1]);
	else son2 = -1;
	if (G.find(makepair(son1, son2)) == G.end()) {
		G[makepair(son1, son2)] = cnt++;
	}
	int id = G[makepair(son1, son2)];
	sum[id]++;
	return id;
}

int dfs_b(int u) {
	int son1, son2;
	if (b[u][0] != -1)
		son1 = dfs_b(b[u][0]);
	else son1 = -1;
	if (b[u][1] != -1)
		son2 = dfs_b(b[u][1]);
	else son2 = -1;
	if (G.find(makepair(son1, son2)) == G.end()) {
		G[makepair(son1, son2)] = 0;
	}
	int id = G[makepair(son1, son2)];
	ans += sum[id];
	return id;
}

int main() {
	int te;
	scanf("%d", &te);
	while (te--) {
		ans = 0;
		int n, m; cnt = 1; G.clear();
		scanf("%d%d", &n, &m);
		for (int i = 0; i <= max(n, m); i++)sum[i] = 0;
		for (int i = 1; i <= n; i++) {
			scanf("%d%d", &a[i][0], &a[i][1]);
		}
		for (int i = 1; i <= m ; i++) {
			scanf("%d%d", &b[i][0], &b[i][1]);
		}
		
		dfs_a(1);
		dfs_b(1);
		printf("%lld\n", ans);
	}
	return 0;
}

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-09 13:05
TMD找工作本来就烦,这东西什么素质啊😡
Beeee0927:hr是超雄了,不过也是有道理的
点赞 评论 收藏
分享
牛客刘北:如果暑期实习是27届的话,你要晚一年才会毕业,企业为什么会等你呢?要搞清时间逻辑呀!27届现在实习只能是在暑假实习,这是日常实习,不是暑期实习。所以多去投日常实习吧,暑期实习肯定不会要你的
点赞 评论 收藏
分享
小叮当411:应该是1-3个月吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务