📜  N元树的同构

📅  最后修改于: 2021-04-17 09:24:23             🧑  作者: Mango

给定两个具有M个节点的N元树。同样,分别给定它们的边缘和根。任务是检查它们是否是同构树。如果两个树都是同构的,则打印“是”,否则打印“否”

例子:

方法:
想法是找出两棵树的规范形式并进行比较。叶节点将“()”返回到其随后的上级。
下面的示例显示了查找规范形式的过程。

下面是上述方法的实现:

// C++ program for the above approach
#include 
using namespace std;
  
// To create N-ary tree
map > tree;
  
// Function which will accept the root
// of the tree and its parent (which
// is initially "-1") and will return
// the canonical form of the tree
string ConvertCanonical(int vertex,
                        int parent)
{
    // In this string vector we will
    // store canonical form of out
    // current node and its subtree
    vector child;
  
    // Loop to the neighbours of
    // current vertex
    for (auto neighbour : tree[vertex]) {
  
        // This is to prevent us from
        // visiting the parent again
        if (neighbour == parent)
            continue;
  
        // DFS call neighbour of our
        // current vertex & it will
        // pushback the subtree-structure
        // of this neighbour into our
        // child vector.
        child.push_back(ConvertCanonical(
            neighbour, vertex));
    }
  
    // These opening and closing
    // brackets are for the
    // current node
    string str = "(";
  
    // Sorting function will re-order
    // the structure of subtree of
    // the current vertex in a
    // shortest-subtree-first manner.
    // Hence we can
    // now compare the two tree
    // structures effectively
    sort(child.begin(), child.end());
  
    for (auto j : child)
        str += j;
  
    // Append the subtree structure
    // and enclose it with "(" 
    // ")" the opening and closing
    // brackets of current vertex
    str += ")";
  
    // return the subtree-structure
    // of our Current vertex
    return str;
}
  
// Function to add edges
void addedge(int a, int b)
{
    tree[a].push_back(b);
    tree[b].push_back(a);
}
  
// Driver code
int main()
{
    // Given N-ary Tree 1
    addedge(1, 3);
    addedge(1, 2);
    addedge(1, 5);
    addedge(3, 4);
    addedge(4, 8);
    addedge(4, 9);
    addedge(3, 6);
    addedge(6, 7);
  
    // Function Call to convert Tree 1
    // into canonical with 3 is the root
    // and the parent of root be "-1"
    string tree1 = ConvertCanonical(3, -1);
  
    // Clearing our current tree
    // before taking input of
    // next tree
    tree.clear();
  
    // Given N-ary Tree 2
    addedge(1, 3);
    addedge(3, 4);
    addedge(3, 5);
    addedge(1, 8);
    addedge(8, 9);
    addedge(1, 2);
    addedge(2, 6);
    addedge(2, 7);
  
    // Function Call to convert Tree 2
    // into canonical
    string tree2 = ConvertCanonical(1, -1);
  
    // Check if canonical form of both
    // tree are equal or not
    if (tree1 == tree2)
        cout << "YES" << endl;
    else
        cout << "NO" << endl;
  
    return 0;
}
输出:
YES

时间复杂度: O(E * log(E)) ,其中E是边数。