-
输入两颗二叉树A,B,判断B是不是A的子结构。
时间限制:1 秒
内存限制:128 兆
题目描述:
-
输入:
-
输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1<=m<=1000):n代表将要输入的二叉树A的节点个数(节点从1开始计数),m代表将要输入的二叉树B的节点个数(节点从1开始计数)。接下来一行有n个数,每个数代表A树中第i个元素的数值,接下来有n行,第一个数Ki代表第i个节点的子孩子个数,接下来有Ki个树,代表节点i子孩子节点标号。接下来m+1行,与树A描述相同。
-
输出:
-
对应每个测试案例,
若B是A的子树输出”YES”(不包含引号)。否则,输出“NO”(不包含引号)。
-
样例输入:
-
7 3 8 8 7 9 2 4 7 2 2 3 2 4 5 0 0 2 6 7 0 0 8 9 2 2 2 3 0 0 1 1 2 0 3 0
-
样例输出:
-
YES NO
-
提示:
-
B为空树时不是任何树的子树。
-
-
方法:暴力法,时间复杂度O(n)。
-
#include <iostream> #include <cstdio> using namespace std; struct BNode { int val; int left, right; BNode() : val(0), left(0), right(0) {} }; const int N = 1001; BNode A[N]; BNode B[N]; bool help(int a, int b) { if (b == 0) return true; else if (a == 0) return false; else if (A[a].val != B[b].val) return false; else return help(A[a].left, B[b].left) && help(A[a].right, B[b].right); } bool isSub(int a, int b) { if (a == 0) return false; if (help(a, b)) return true; if (isSub(A[a].left, b)) return true; return isSub(A[a].right, b); } int main(void) { int n, m; while (scanf("%d%d", &n, &m) != EOF) { for (int i = 1; i <= n; ++i) { scanf("%d", &A[i].val); A[i].left = 0; A[i].right = 0; } int k; for (int i = 1; i <= n; ++i) { scanf("%d", &k); if (k > 0) scanf("%d", &A[i].left); if (k > 1) scanf("%d", &A[i].right); } for (int i = 1; i <= m; ++i) { scanf("%d", &B[i].val); B[i].left = 0; B[i].right = 0; } for (int i = 1; i <= m; ++i) { scanf("%d", &k); if (k > 0) scanf("%d", &B[i].left); if (k > 1) scanf("%d", &B[i].right); } if (m <= n && m != 0 && isSub(1, 1)) printf("YES\n"); else printf("NO\n"); } return 0; }