图中的路径
题目描述:
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:
Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0 | 1 / \ 2 3
return [1]
Example 2:
Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2 \ | / 3 | 4 | 5
return [3, 4]
Note:
(1) 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.”
(2) The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.
问题分析:
需要找到一些顶点,使其到其他任一顶点的最长距离最小。
受到discussion的启发。建立图后不断去掉最外层(相邻节点只有一个)的叶节点,倘若某次去除后顶点集为空,则最后一次所去除的所有顶点为所求的顶点。
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector< pair<int, int> >& edges) {
vector<node*> nodes;
for (int i = 0; i < n; i++) {
nodes.push_back(new node(i));
}
for (int i = 0; i < edges.size(); i++) {
nodes[edges[i].first]->neighbor.insert(nodes[edges[i].second]);
nodes[edges[i].second]->neighbor.insert(nodes[edges[i].first]);
}
set<node*> leaves;
set<node*> del;
while(1) {
for (vector<node*>::iterator i = nodes.begin(); i != nodes.end(); i++){
if (((*i)->neighbor).size() <= 1) {
leaves.insert(*i);
if (((*i)->neighbor).size() == 1) del.insert(*(((*i)->neighbor).begin()));
nodes.erase(i);
i--;
}
}
for (set<node*>::iterator i = del.begin(); i != del.end(); i++){
for (set<node*>::iterator j = leaves.begin(); j != leaves.end(); j++) {
(*i)->neighbor.erase(*j);
}
}
if (nodes.size() == 0) {
vector<int> roots;
for (set<node*>::iterator j = leaves.begin(); j != leaves.end(); j++) {
roots.push_back((*j)->num);
delete *j;
}
return roots;
}
for (set<node*>::iterator j = leaves.begin(); j != leaves.end(); j++) {
delete *j;
}
leaves.clear();
del.clear();
}
}
private:
struct node{
int num;
set<node*> neighbor;
node(int n): num(n) {}
};
};
提交结果可以说是十分惨烈了…
66 / 66 test cases passed.
Status: Accepted
Runtime: 1025 ms
Your runtime beats 2.71 % of cpp submissions.
……..
其实这题真的花了好长时间AC….大大超过了预期…大概是对图还不熟悉….
至于为什么跑出来还是那么慢…再参考了一下其他的答案
主要是实现方式出了一些问题。
有过多多余的遍历操作和集合的操作。
要继续熟练吧。