5-3 树的同构 (25分)

5-3 树的同构   (25分)

给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。


图1


图2

现给定两棵树,请你判断它们是否是同构的。

输入格式:

输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (10),即该树的结点数(此时假设结点从0到N1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。

输出格式:

如果两棵树是同构的,输出“Yes”,否则输出“No”。

输入样例1(对应图1):

8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -

输出样例1:

Yes

输入样例2(对应图2):

8
B 5 7
F - -
A 0 3
C 6 -
H - -
D - -
G 4 -
E 1 -
8
D 6 -
B 5 -
E - -
H - -
C 0 2
G - 3
F - -
A 1 4

输出样例2:

No
 
  • 时间限制:400ms
  • 内存限制:64MB
  • 代码长度限制:16kB
  • 判题程序:系统默认
  • 作者:陈越
  • 单位:浙江大学

题目判定 


http://pta.patest.cn/pta/test/15/exam/4/question/711

/* 
22分代码,待解决
5-3 树的同构   (25分)
http://pta.patest.cn/pta/test/15/exam/4/question/711
*/  
#include <cstdio>  
#include <cstdlib>  
#include <iostream>  
#include <vector>  
#include <queue>  
#include <map>
#include <stack>
#include <iterator>
#include <algorithm>  
  
using namespace std;  
  
typedef struct node{
	char data;
	struct node* left ;
	struct node* right ;
	node(char _data = '-')
	{
		data = _data ;
		left = NULL ;
		right = NULL ;
	}
}Bnode;

struct data{
	char c ;
	int left ;
	int right ;
};
data vd[10] ;

int fa[10];

int find(int x)
{
	if(x == fa[x])
		return x ;
	return fa[x] = find(fa[x]);
}
void merg(int x, int y)
{
	fa[find(y)] =  find(x);
}

Bnode* createTree(Bnode* root , int num)
{
	root = new node(vd[num].c);
	int left = vd[num].left ;
	int right =  vd[num].right ;
	if(left != -1)
	{
		root->left = createTree(root->left , left);
	}
	if(right != -1)
	{
		root->right= createTree(root->right , right);
	}
	return root ;
}

struct mydata{
	char c ;
	char le;
	char ri;
};

bool cmp(mydata d1,mydata d2)
{
	return d1.c < d2.c ;
}

int main()  
{  
    //freopen("in.txt","r",stdin);  
    //freopen("out.txt","w",stdout);  
	int i , n1,n2;
	char c1,cLeft,cRight;
	while(scanf("%d\n",&n1) != EOF)
	{	
		for(i = 0; i < n1 ; i++)
			fa[i] = i ;
		for(i = 0 ; i < n1 ;i ++)
		{
			scanf("%c %c %c\n",&c1,&cLeft,&cRight);
			vd[i].c = c1;
			if(cLeft == '-')
			{
				vd[i].left = -1;
			}else{
				vd[i].left = cLeft - '0' ;
				merg(i,vd[i].left);
			}
			if(cRight == '-')
			{
				vd[i].right = -1;
			}else{
				vd[i].right = cRight - '0' ;
				merg(i,vd[i].right);
			}
		}
		int rootNum1 = find(0);
		Bnode* root1 = NULL;
		root1 = createTree(root1,rootNum1);

		scanf("%d\n",&n2);
		for(i = 0; i < n2 ; i++)
			fa[i] = i ;
		for(i = 0 ; i < n2 ;i ++)
		{
			scanf("%c %c %c\n",&c1,&cLeft,&cRight);
			vd[i].c = c1;
			if(cLeft == '-')
			{
				vd[i].left = -1;
			}else{
				vd[i].left = cLeft - '0' ;
				merg(i,vd[i].left);
			}
			if(cRight == '-')
			{
				vd[i].right = -1;
			}else{
				vd[i].right = cRight - '0' ;
				merg(i,vd[i].right);
			}
		}
		int rootNum2 = find(0);
		Bnode* root2 = NULL;
		root2 = createTree(root2,rootNum2);

		if(n1 != n2)
		{
			printf("No\n");
			continue;
		}

		vector<mydata> v1 ,v2;
		int len1 = 0 , len2 = 0 ;
		queue<Bnode*> que ;
		que.push(root1);
		while(!que.empty())
		{
			Bnode* rt = que.front();
			que.pop();
			mydata md ;
			md.c = rt->data ;
			md.le = '-';
			md.ri = '-';
			if(rt->left != NULL){
				md.le = rt->left->data ;
				que.push(rt->left);
			}
			if(rt->right != NULL){
				md.ri = rt->right->data;
				que.push(rt->right);
			}
			v1.push_back(md);
			len1 ++ ;
		}
		sort(v1.begin() , v1.end() , cmp);

		que.push(root2);
		while(!que.empty())
		{
			Bnode* rt = que.front();
			que.pop();
			mydata md ;
			md.c = rt->data ;
			md.le = '-';
			md.ri = '-';
			if(rt->left != NULL){
				md.le = rt->left->data ;
				que.push(rt->left);
			}
			if(rt->right != NULL){
				md.ri = rt->right->data;
				que.push(rt->right);
			}
			v2.push_back(md);
			len2 ++ ;
		}
		sort(v2.begin() , v2.end() , cmp);
		
		if(len1 != len2 )
		{
			printf("No\n");
			continue;
		}

		bool flag = false ;
		for(i = 0 ; i < len1 ;i++)
		{
			mydata md1 = v1[i];
			mydata md2 = v2[i];
			flag = false;
			if(md1.c == md2.c)
			{
				if(md1.le == md2.le && md1.ri == md2.ri)
					flag = true;
				else if(md1.le == md2.ri && md1.ri == md2.le)
					flag = true;
				else
					flag = false;
			}
			if(flag == false)
				break;
		}
		if(flag)
			printf("Yes\n");
		else
			printf("No\n");
	}
    return 0 ;  
}  


段错误 原因 是 0 0 的情况没有特殊考虑


下面的递归 ac代码

/*
5-3 树的同构   (25分)
http://pta.patest.cn/pta/test/15/exam/4/question/711
*/
#include <cstdio>    
#include <cstdlib>    
#include <iostream>    
#include <vector>    
#include <queue>    
#include <map>  
#include <stack>  
#include <iterator>  
#include <algorithm>    

using namespace std;

#define N 12

typedef struct node{
	char data;
	struct node* left;
	struct node* right;
	node(char _data = '-')
	{
		data = _data;
		left = NULL;
		right = NULL;
	}
}Bnode;

struct data{
	char c;
	int left;
	int right;
};
data vd[N];

int fa[N];

int find(int x)
{
	if (x == fa[x])
		return x;
	return fa[x] = find(fa[x]);
}
void merg(int x, int y)
{
	fa[find(y)] = find(x);
}

Bnode* createTree(Bnode* root, int num)
{
	root = new node(vd[num].c);
	int left = vd[num].left;
	int right = vd[num].right;
	if (left != -1)
	{
		root->left = createTree(root->left, left);
	}
	if (right != -1)
	{
		root->right = createTree(root->right, right);
	}
	return root;
}

struct mydata{
	char c;
	char le;
	char ri;
};

bool isomorphism(Bnode* root1, Bnode* root2)
{
	if (root1 == NULL && root2 == NULL)
		return true;
	if (root1 != NULL && root2 == NULL)
		return false;
	if (root1 == NULL && root2 != NULL)
		return false;
	if (root1->data != root2->data)
		return false;

	// 左子树 都为空
	if (root1->left == NULL  && root2->left == NULL)
		return isomorphism(root1->right, root2->right);

	if (root1->left != NULL && root2->left == NULL) // 需要交换子树判断
	{
		bool b1 = isomorphism(root1->left, root2->right);
		bool b2 = isomorphism(root1->right, root2->left);
		return b1&&b2;
	}
	else if (root1->left == NULL && root2->left != NULL)//同上
	{
		bool b1 = isomorphism(root1->left, root2->right);
		bool b2 = isomorphism(root1->right, root2->left);
		return b1&&b2;
	}
	else{

		if (root1->left->data == root2->left->data){ //判断左,右子树  而不是 左右子树的子树
			bool b1 = isomorphism(root1->left, root2->left);
			bool b2 = isomorphism(root1->right, root2->right);
			return b1&&b2;
		}
		else{
			bool b1 = isomorphism(root1->left, root2->right); // 当前树交换 再判断
			bool b2 = isomorphism(root1->right, root2->left);
			return b1&&b2;
		}
	}

	return false;
}


int main()
{
	//freopen("in.txt","r",stdin);    
	//freopen("out.txt","w",stdout);    
	int i, n1, n2;
	char c1, cLeft, cRight;
	while (scanf("%d\n", &n1) != EOF)
	{
		//使用并查集
		for (i = 0; i < n1; i++)
			fa[i] = i;
		for (i = 0; i < n1; i++)
		{
			scanf("%c %c %c\n", &c1, &cLeft, &cRight);
			vd[i].c = c1;
			if (cLeft == '-')
			{
				vd[i].left = -1;
			}
			else{
				vd[i].left = cLeft - '0';
				merg(i, vd[i].left);
			}
			if (cRight == '-')
			{
				vd[i].right = -1;
			}
			else{
				vd[i].right = cRight - '0';
				merg(i, vd[i].right);
			}
		}
		Bnode* root1 = NULL;
		if (n1 > 0){
			int rootNum1 = find(0);	
			root1 = createTree(root1, rootNum1);//构造树1
		}

		scanf("%d\n", &n2);
		for (i = 0; i < n2; i++)
			fa[i] = i;
		for (i = 0; i < n2; i++)
		{
			scanf("%c %c %c\n", &c1, &cLeft, &cRight);
			vd[i].c = c1;
			if (cLeft == '-')
			{
				vd[i].left = -1;
			}
			else{
				vd[i].left = cLeft - '0';
				merg(i, vd[i].left);
			}
			if (cRight == '-')
			{
				vd[i].right = -1;
			}
			else{
				vd[i].right = cRight - '0';
				merg(i, vd[i].right);
			}
		}
		Bnode* root2 = NULL;
		if (n2 > 0){
			int rootNum2 = find(0);
			root2 = createTree(root2, rootNum2);//构造树2
		}

		if (n1 != n2)
		{
			printf("No\n");
			continue;
		}

		bool flag = isomorphism(root1, root2);
		if (flag)
			printf("Yes\n");
		else
			printf("No\n");

	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值