拼題A 樹的同構
題目描述:
給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因爲我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。
現給定兩棵樹,請你判斷它們是否是同構的。
輸入格式:
輸入給出2棵二叉樹樹的信息。對於每棵樹,首先在一行中給出一個非負整數N (≤10),即該樹的結點數(此時假設結點從0到N−1編號);隨後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
根據題意很容易知道判斷兩棵樹是否同構只需判斷這兩棵樹同一結點的左右子樹是否相同(順序可以顛倒),題目所給的結點的順序不同,所以先排個序再操作。
處理特殊字符 ‘ - ’:如果不考慮特殊字符的話,就可以直接判斷左右子樹了,然後我輸出了一下‘ - ’ - ‘ 0 ’的結果發現爲-3,那當我們每次將結點的左右子樹轉換爲整型時,就特判一下,如果爲負,就讓左/右的數值爲一個不可能出現的數10(題目說了N <= 10),這裏我開了兩個數組分別存兩棵樹所對應的下標的數據,然後讓兩個數組[10]都爲’ - ',這樣就可以正常判斷了。
上代碼:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Tree
{
char data;
char left_tree, right_tree;
int id;
};
Tree t1[20], t2[20];
char a[20], b[20];
int n;
bool cmp(Tree a, Tree b)
{
return a.data < b.data;
}
bool judge_tg()
{
for(int i = 0; i < n; i++)
{
if(t1[i].data != t2[i].data) // 既然排過序了,那麼如果同構的話每個結點的數據應該都相同,不同則不可能同構
return false;
int l1, l2, r1, r2;
l1 = t1[i].left_tree - '0';
if(l1 < 0)
l1 = 10;
l2 = t2[i].left_tree - '0';
if(l2 < 0)
l2 = 10;
r1 = t1[i].right_tree - '0';
if(r1 < 0)
r1 = 10;
r2 = t2[i].right_tree - '0';
if(r2 < 0)
r2 = 10;
if( !( (a[l1] == b[l2] && a[r1] == b[r2] ) || ( a[l1] == b[r2] && a[r1] == b[l2]) ) )
return false;
}
return true;
}
int main()
{
//printf("%d\n", '-'-'0'); // -3
a[10] = '-';
b[10] = '-';
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
getchar();
scanf("%c %c %c", &t1[i].data, &t1[i].left_tree, &t1[i].right_tree);
t1[i].id = i;
a[i] = t1[i].data;
}
sort(t1, t1 + n, cmp);
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
getchar();
scanf("%c %c %c", &t2[i].data, &t2[i].left_tree, &t2[i].right_tree);
t2[i].id = i;
b[i] = t2[i].data;
}
sort(t2, t2 + n, cmp);
if(judge_tg())
printf("Yes\n");
else
printf("No\n");
return 0;
}