1. 程式人生 > >樹的同構(25 分)

樹的同構(25 分)

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。


圖1


圖2

現給定兩棵樹,請你判斷它們是否是同構的。

輸入格式:

輸入給出2棵二叉樹樹的資訊。對於每棵樹,首先在一行中給出一個非負整數N (),即該樹的結點數(此時假設結點從0到N1編號);隨後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;
}