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

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

Hint

The two trees in the first sample look like this.

References


Author: ZHUANG, Junyuan; WU, Zejun
Contest: The 9th Zhejiang Provincial Collegiate Programming Contest

AC代码:

 #include <stdio.h>
#include <string.h>
#include <algorithm> using namespace std; #define MAXN 100010 struct Edge {
int v, e, label;
Edge *link;
} edge[MAXN], *adj[MAXN]; int totE;
int f[MAXN], g[MAXN], val[MAXN], degree[MAXN], fa[MAXN];
int vec[], Q[MAXN];
int a = , b = , pp = , q = ; void addEdge(int u, int v, int label) {
Edge *p = &edge[totE++];
p->v = v;
p->label = label;
p->link = adj[u];
adj[u] = p;
} void cal(int n, int f[MAXN]) {
totE = ;
memset(adj, NULL, sizeof(adj));
memset(degree, , sizeof(degree));
for (int i = ; i <= n; ++i) {
int l, r;
scanf("%d%d", &l, &r);
if (l != -) {
addEdge(i, l, );
++degree[i];
fa[l] = i;
}
if (r != -) {
addEdge(i, r, );
++degree[i];
fa[r] = i;
}
}
int l = , r = ;
for (int i = ; i <= n; ++i) {
if (!degree[i])
Q[r++] = i;
}
while (l != r) {
int u = Q[l++];
Edge *p = adj[u];
int total = ;
while (p) {
vec[total++] = (long long) val[p->v] * p->label % q;
p = p->link;
}
val[u] = a;
for (int i = ; i < total; ++i) {
val[u] = (long long) val[u] * pp % q ^ vec[i] % q;
}
if(--degree[fa[u]] == ) Q[r++] = fa[u];
}
for (int i = ; i <= n; ++i)
f[i] = val[i];
sort(f + , f + + n);
} int main() {
int T;
scanf("%d", &T);
for (int cas = ; cas <= T; ++cas) {
int n, m;
scanf("%d%d", &n, &m);
cal(n, f);
cal(m, g);
int p1 = , p2 = ;
long long res = ;
while (p1 <= n && p2 <= m) {
if (f[p1] > g[p2])
++p2;
else if (f[p1] < g[p2])
++p1;
else {
int p3 = p1;
while (p3 + <= n && f[p3 + ] == f[p1])
++p3;
int p4 = p2;
while (p4 + <= m && g[p4 + ] == g[p2])
++p4;
res += (long long) (p3 - p1 + ) * (p4 - p2 + );
p1 = p3 + ;
p2 = p4 + ;
}
}
printf("%lld\n", res);
}
return ;
}

最新文章

  1. C# 图片超过指定大小将压缩到指定大小不失真
  2. 关于在VS 上发布网站
  3. Ruby on Rails框架开发学习
  4. 简单理解JavaScript闭包
  5. Microsoft SQL Server,附加数据库 错误:Error 916解决方法
  6. linux在shell date获取时间的相关操作
  7. 转载 SharePoint Foundation和SharePoint Server的区别
  8. 【HDOJ】2268 How To Use The Car
  9. jQuery的事件和动画
  10. docker !veth
  11. android AlarmManager讲解
  12. MySQL 多表查询 学习与练习
  13. .net公众号开发自动回复消息
  14. Javascript 继承和多态
  15. Spring技术内幕总结 - AOP概述
  16. 学习C语言以及C语言基础调查
  17. 如何使用Java执行cmd命令
  18. vmware打开vmx文件不能创建虚拟机的问题
  19. Spring知识点小结(二)
  20. 使用SWT技术的跨平台移动应用开发库Tabris

热门文章

  1. Android --RatingBar的使用
  2. 关于SASS---&gt;推荐使用
  3. UVA 558 判定负环,spfa模板题
  4. HTML5中video 和 ogg
  5. 深入浅出 - Android系统移植与平台开发(三)- 编译并运行Android4.0模拟器
  6. 20145330《Java程序设计》第一次实验报告
  7. Hadoop、Zookeeper、Hbase分布式安装教程
  8. 七、考反映小游戏《苹果iOS实例编程入门教程》
  9. ORACLE 查看锁
  10. preventDefault()方法