http://ac.jobdu.com/problem.php?pid=1520
题目描述:
输入两颗二叉树A,B,判断B是不是A的子结构。
先建树,为了后面匹配时提高速度,每个结点做一个索引
然后枚举A中的结点是否与B的树根相同,若相同,则遍历B的同时遍历A,判断是否相似
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> struct Tree{ int v; Tree *left,*right; }* Atree_p[1099],* Btree_p[1099]; int n,m; int nodeL,nodeR; void build(Tree *thead,int num,int v){ thead->v=v; if(num==0){ thead->left=NULL; thead->right=NULL; } if(num==1){ Atree_p[nodeL] =thead->left=new Tree; thead->right=NULL; } if(num==2){ Atree_p[nodeL] = thead->left=new Tree; Atree_p[nodeR] = thead->right=new Tree; } } void build_B(Tree *thead,int num,int v){ thead->v=v; if(num==0){ thead->left=NULL; thead->right=NULL; } if(num==1){ Btree_p[nodeL] =thead->left=new Tree; thead->right=NULL; } if(num==2){ Btree_p[nodeL] = thead->left=new Tree; Btree_p[nodeR] = thead->right=new Tree; } } int AtreeV[1099],BtreeV[1099]; int dif=0; int dfs(Tree* Athead,Tree *Bthead){ if(dif==1)return 1; if(Bthead->left!=NULL){ if(Athead->left==NULL||(Athead->left->v)!=(Bthead->left->v)){ dif=1; return 1; } dfs(Athead->left,Bthead->left); } if(Bthead->right!=NULL){ if(Athead->right==NULL||(Athead->right->v)!=(Bthead->right->v)){ dif=1; return 1; } dfs(Athead->right,Bthead->right); } if(dif==1)return 1; else return 0; } int find(){ int i,j; for(i=1;i<=n;i++){ if((Atree_p[i]->v)!=(Btree_p[1]->v))continue; dif=0; if(dfs(Atree_p[i],Btree_p[1])==0) return 1; } return 0; } int main(){ int i,j,k,num,no; while(scanf("%d%d",&n,&m)!=EOF){ for(i=1;i<=n;i++){ scanf("%d",&AtreeV[i]); } Atree_p[1]=new Tree; for(i=1;i<=n;i++){ scanf("%d",&num); if(num==1){ scanf("%d",&nodeL); } if(num==2){ scanf("%d%d",&nodeL,&nodeR); }build(Atree_p[i],num,AtreeV[i]); } //B for(i=1;i<=m;i++){ scanf("%d",&BtreeV[i]); } Btree_p[1]=new Tree; for(i=1;i<=m;i++){ scanf("%d",&num); if(num==1){ scanf("%d",&nodeL); } if(num==2){ scanf("%d%d",&nodeL,&nodeR); }build_B(Btree_p[i],num,BtreeV[i]); } //B为空树时不是任何树的子树 if(m==0||find()==0){ printf("NO\n"); }else{ printf("YES\n"); } } return 0; }