最小树高的根(Roots of a tree which give minimum height)

来源:互联网 发布:js触发后台事件 编辑:程序博客网 时间:2024/05/22 17:24

原文地址:http://www.geeksforgeeks.org/roots-tree-gives-minimum-height/

Given an undirected graph, which has tree characteristics. It is possible to choose any node as root, the task is to find those nodes only which minimize the height of tree.

已知一个无向图,这个图有树的特征。它可以选择任意节点为root,那么这个题目的任务就是找到可以让变成高度最小的树的节点

Example:

In below diagram all node are made as root one by one, we can see that when 3 and 4 are root, height of tree is minimum(2) so {3, 4} is our answer.

例如:

在下图中所有的节点都可以依次作为root,我们可以看到当3和4作为root的时候,树的高度(2)最小,所以{3,4}是我们想要的答案。

We can solve this problem by first thinking about 1-D solution, that is if a longest graph is given, then the node which will minimize the height will be mid node if total node count is odd or mid two node if total node count is even. This solution can be reached by following approach – Start two pointers from both end of the path and move one step each time, until pointers meet or one step away, at the end pointers will be at those nodes which will minimize the height because we have divided the nodes evenly so height will be minimum.

我们首先想到的是关于1维的解决方法,那就是如果给定一个最长的图,那么能够让树高度最小的节点将是中间的节点,如果总节点树是奇数的话,那就是中间节点,如果是偶数的话,那就是中间的两个节点。这个方案可以通过一下方法达到-开始两个指针指向路径的两端,每次移动一步,直到两个指针相遇或者相差一步,最后指针将会指向最小化树高的节点,因为我们已经将节点均匀地分开,所以得到的就是最小高度。

Same approach can be applied to a general tree also. Start pointers from all leaf nodes and move one step inside each time, keep combining pointers which overlap while moving, at the end only one pointer will remain on some vertex or two pointers will remain at one distance away. Those node represent the root of the vertex which will minimize the height of the tree.

同样的方法可以应用在一般的树上。开始指针全部指向叶子节点,然后每次内部移动一步,保持结合这些在移动中会重叠的指针,最后只有一个指针仍然在某个定点,或者有两个指针仍然相距一个距离。这些节点代表的就是定点的root,也就是最小化树高的root。

So we can have only one root or at max two root for minimum height depending on tree structure as explained above. For implementation we will not use actual pointers instead we’ll follow BFS like approach, In starting all leaf node are pushed into the queue, then they are removed from tree, next new leaf node are pushed in queue, this procedure keeps on going until we have only 1 or 2 node in our tree, which represent the result.

As we are accessing each node once, total time complexity of solution is O(n).

所以我们在最小树高上只有一个root或者最多两个root,这依赖于上述所描述的树的结构。在具体的实现中,我们不用真正的指针,而是用类似与BFS(广度优先搜索)方法,一开始将所有的叶子节点都push进队列中,然后它们被从树上移除,然后新的叶子节点又被push到队列中,这个过程一直持续直到我们只有一个或者两个节点在树上,这就是结果。

正如我们要访问每个节点,这个方法的总时间复杂的是O(n)。

//  C++ program to find root which gives minimum height to tree#include <bits/stdc++.h>using namespace std; // This class represents a undirected graph using adjacency list// representationclass Graph{public:    int V; // No. of vertices     // Pointer to an array containing adjacency lists    list<int> *adj;     // Vector which stores degree of all vertices    vector<int> degree;     Graph(int V);            // Constructor    void addEdge(int v, int w);   // To add an edge     // function to get roots which give minimum height    vector<int> rootForMinimumHeight();}; // Constructor of graph, initializes adjacency list and// degree vectorGraph::Graph(int V){    this->V = V;    adj = new list<int>[V];    for (int i = 0; i < V; i++)        degree.push_back(0);} // addEdge method adds vertex to adjacency list and increases// degree by 1void Graph::addEdge(int v, int w){    adj[v].push_back(w);    // Add w to v’s list    adj[w].push_back(v);    // Add v to w’s list    degree[v]++;            // increment degree of v by 1    degree[w]++;            // increment degree of w by 1} //  Method to return roots which gives minimum height to treevector<int> Graph::rootForMinimumHeight(){    queue<int> q;     //  first enqueue all leaf nodes in queue    for (int i = 0; i < V; i++)        if (degree[i] == 1)            q.push(i);     //  loop untill total vertex remains less than 2    while (V > 2)    {        for (int i = 0; i < q.size(); i++)        {            int t = q.front();            q.pop();            V--;             // for each neighbour, decrease its degree and            // if it become leaf, insert into queue            for (auto j = adj[t].begin(); j != adj[t].end(); j++)            {                degree[*j]--;                if (degree[*j] == 1)                    q.push(*j);            }        }    }     //  copying the result from queue to result vector    vector<int> res;    while (!q.empty())    {        res.push_back(q.front());        q.pop();    }    return res;} //  Driver code to test above methodsint main(){    Graph g(6);    g.addEdge(0, 3);    g.addEdge(1, 3);    g.addEdge(2, 3);    g.addEdge(4, 3);    g.addEdge(5, 4);     vector<int> res = g.rootForMinimumHeight();    for (int i = 0; i < res.size(); i++)        cout << res[i] << " ";    cout << endl;}

Output:

输出:

3 4

0 0
原创粉丝点击