樹的同構(25 分)
阿新 • • 發佈:2019-02-13
給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。
圖1
圖2
輸入格式:
輸入給出2棵二叉樹樹的資訊。對於每棵樹,首先在一行中給出一個非負整數N (≤),即該樹的結點數(此時假設結點從0到N−1編號);隨後N行,第i行對應編號第i個結點,給出該結點中儲存的1個英文大寫字母、其左孩子結點的編號、右孩子結點的編號。如果孩子結點為空,則在相應位置上給出“-”。給出的資料間用一個空格分隔。注意:題目保證每個結點中儲存的字母是不同的。
輸出格式:
如果兩棵樹是同構的,輸出“Yes”,否則輸出“No”
先找到根節點,然後根據根節點,同時遞迴兩棵樹,如果不符合調節返回就可以,還有注意就是一個事情,自己一開始沒有想到,就是這棵樹只有左結點,類似一條直線。
其實有一個更簡單的做法,就是不斷用vector的二維陣列存每個結點子結點,然後利用vector的 == 過載,就可以直接判斷,對應結點的子結點是否相通,就可以判斷是否是同構的了
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> #include <map> #include <queue> #include <math.h> #include <stack> #include <utility> #include <string> #include <sstream> #include <cstdlib> #include <set> #define LL long long using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1000 + 10; int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; int Root1,Root2; struct TreeNode { char Data; int Left; int Right; TreeNode(char a,int l,int r) { Data = a; Left = l; Right = r; } }; vector<TreeNode> TB1; vector<TreeNode> TB2; int vis1[maxn]; int vis2[maxn]; int n,m; int ans; void init() { memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); } int judge(int a,int b) { if(a == -1 && b == -1) return 1; if(a == -1 && b != -1) return 0; if(a != -1 && b == -1) return 0; if(TB1[a].Data != TB2[b].Data) return 0; if(TB1[a].Left == -1 && TB2[b].Left == -1) return judge(TB1[a].Right,TB2[b].Right); if((TB1[a].Left != -1 && TB2[b].Left != -1)&&(TB1[TB1[a].Left].Data == TB2[TB2[b].Left].Data)) return ( judge( TB1[a].Left, TB2[b].Left )&&judge( TB1[a].Right, TB2[b].Right ) ); else return ( judge( TB1[a].Left, TB2[b].Right )&&judge( TB1[a].Right, TB2[b].Left ) ); } int main() { scanf("%d",&n); TB1.clear(); TB2.clear(); Root1 = -1; Root2 = -1; for(int i = 0; i < n; i++) { char a,b,c; cin>>a>>b>>c; int left,right; if(b != '-') { left = b - '0'; vis1[left] = 1; } else { left = -1; } if(c != '-') { right = c - '0'; vis1[right] = 1; } else { right = -1; } TB1.push_back(TreeNode(a,left,right)); } for( int i = 0; i < n; i++) { if(!vis1[i]) { Root1= i; break; } } scanf("%d",&m); if(n != m) { puts("No"); return 0; } init(); for(int i = 0; i < m; i++) { char a,b,c; cin>>a>>b>>c; int left,right; if(b != '-') { left = b - '0'; vis2[left] = 1; } else { left = -1; } if(c != '-') { right = c - '0'; vis2[right] = 1; } else { right = -1; } TB2.push_back(TreeNode(a,left,right)); } for( int i = 0; i < m; i++) { if(!vis2[i]) { Root2= i; break; } } if(judge(Root1,Root2)) { cout<<"Yes"<<endl; } else cout<<"No"<<endl; return 0; }