-
题目描述:
-
输入两颗二叉树A,B,判断B是不是A的子结构。
-
输入:
-
输入可能包含多个测试样例,输入以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为空树时不是任何树的子树。
/*先根据提题意,建立二叉树,先序遍历,最后用kmp进行匹配*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 1002
typedef struct node
{
int data ;
struct node *left , *right ;
}node , *tree ;
int sa[MAX] ,ka , sb[MAX] , kb = 0 ,next[MAX];
void Init(tree A[])
{
for(int i = 1 ; i <MAX ; i ++)
A[i] = NULL ;
return ;
}
void Inorder(tree T)
{
if(T){
sa[ka++] = T->data;
Inorder(T->left);
Inorder(T->right);
}
}
void Inorder1(tree T)
{
if(T){
sb[kb++] = T->data;
Inorder1(T->left);
Inorder1(T->right);
}
}
void pre_next(int k )
{
int i =0 , j = - 1 ;
next[0] = -1 ;
while(i<k)
{
if( j == -1 || sa[i] == sb[j])
{
j++;
i++ ;
next[i] = j ;
}
else
j = next[j] ;
}
}
bool KMP()
{
int i = 0 , j = 0 ;
int lena = ka ;
int lenb = kb ;
while( i <= lena)
{
if(sa[i]== sb[j])
{
i++;
j++;
}
else
{
if(next[j] == - 1)
{
j = 0 ;
i++;
}
else
j= next[j] ;
}
if(j== lenb)
return true;
}
return false;
}
int main(void)
{
int n , m ;
while(scanf("%d %d",&n,&m)!=EOF){
int i ;
tree A[MAX] , B[MAX] ;
Init(A);
Init(B) ;
for( i = 1 ; i <= n ; i++){
int cnt ;
scanf("%d",&cnt);
tree p ;
p = (node *)malloc(sizeof(node)) ;
p->data = cnt ;
p->left = p->right = NULL ;
A[i] = p ;
}
int num , l , r ;
for( i = 1 ; i <= n ; i ++)
{
scanf("%d",&num);
switch(num){
case 2:{
scanf("%d %d",&l,&r);
A[i]->left = A[l] ;
A[i]->right = A[r] ;
break;
}
case 1:{
scanf("%d",&l) ;
A[i]->left = A[l] ;
break;
}
case 0:{
break;
}
}
}
int cnt ;
for( i = 1 ; i <= m ; i++){
scanf("%d",&cnt);
tree p ;
p = (node *)malloc(sizeof(node)) ;
p->data = cnt ;
p->left = p->right = NULL ;
B[i] = p ;
}
for( i = 1 ; i <= m ; i ++)
{
scanf("%d",&num);
switch(num){
case 2:{
scanf("%d %d",&l,&r);
B[i]->left = B[l] ;
B[i]->right = B[r] ;
break;
}
case 1:{
scanf("%d",&l) ;
B[i]->left = B[l] ;
break;
}
case 0:
break;
}
}
ka = kb = 0 ;
Inorder(A[1]);
Inorder1(B[1] );
pre_next(kb ) ;
if(KMP())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}