For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format
The graph contains n
nodes which are labeled from 0
to n - 1
. You will be given the number n
and a list of undirected edges
(each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
.
Example 1 :
Input:n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0 | 1 / \ 2 3 Output:[1]
Example 2 :
Input:n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2 \ | / 3 | 4 | 5 Output:[3, 4]
Note:
- According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”
- The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.
在一副可以形成树的图中,满足题目要求的结点个数只能为2,1或者0,当结点个数为0时,满足题目要求的结点个数也为0。现在假设存在三个结点满足题目要求,那么这三个结点为根的树的高度都是相同的,并且由于此图中每两个结点都有唯一一条路径相通,那么这这三个结点可以由一条路径相连,假设以位于中间的那个结点为根的树的高度为n,那么在另外两个结点中必然有一个结点满足其为根的树的最大高度为n+distance(中间的结点,此结点),这样子,该结点就不再满足题目的要求。所以满足要求的结点个数只能为1或者2(总结点个数不为0)。
那么现在想要求这两个点或者一个点,以此结点为根的树的高度是最小的,树的高度是由距离根结点最远的叶结点决定的,我们找到在图中距离最远的两个叶结点,那么这两个结点E,F的中间一个A或者两个结点A,B就是题目所求。因为无论哪一点到达E和F的最大值都要大于A和B。那么存不存在某个叶结点G到A或者B的距离大于A和B达到E,F的距离呢,当然不存在这样点,否则的话EF就不是整个图中相距最远的两个叶结点了。
从最底层的叶结点开始,一层一层地往上删除,最终剩下的一个或者两个结点就是要求的点。
#include <iostream>
#include <cstdlib>
#include <vector>
#include <iterator>
#include <string>
#include <queue>
#include <unordered_set>
using namespace std;
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges)
{
if (n == 1)return { 0 };
vector<int> result;
vector<unordered_set<int>> ee(n);
for (int i = 0; i < edges.size(); i++)
{
ee[edges[i].first].insert(edges[i].second);
ee[edges[i].second].insert(edges[i].first);
}
queue<int> que;
for (int i = 0; i < n; i++)if (ee[i].size() == 1)que.push(i);
while (n > 2)
{
int size = que.size();
n -= size;
for (int i = 0; i < size; i++)
{
int front = que.front(); que.pop();
int temp = *(ee[front].begin());
ee[temp].erase(front);
if (ee[temp].size() == 1)que.push(temp);
}
}
while (!que.empty())
{
result.push_back(que.front());
que.pop();
}
return result;
}
int main()
{
pair<int, int> a(0, 3);
pair<int, int> b(1, 3);
pair<int, int> c(2, 3);
pair<int, int> d(4, 3);
pair<int, int> e(5, 4);
vector<pair<int, int>> edges;
edges.push_back(a);
edges.push_back(b);
edges.push_back(c);
edges.push_back(d);
edges.push_back(e);
vector<int> result = findMinHeightTrees(6, edges);
for (auto f : result)
cout << f << " ";
cout << endl;
system("pause");
return 0;
}