-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathminimum-height-trees.cpp
93 lines (72 loc) · 2.53 KB
/
minimum-height-trees.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
std::vector<std::vector<int>> gr(n);
for (auto& e : edges) {
gr[e.front()].push_back(e.back());
gr[e.back()].push_back(e.front());
}
std::vector<int> dist(n, n+2);
dist[0] = 0;
std::queue<int> ord;
ord.push(0);
while (ord.size()) {
auto cur = ord.front();
ord.pop();
for (const auto& nei : gr[cur]) {
if (dist[nei] > 1 + dist[cur]) {
dist[nei] = 1 + dist[cur];
ord.push(nei);
}
}
}
auto it = std::max_element(dist.begin(),dist.end());
int node = std::distance(dist.begin(), it);
dist.assign(n, n+2);
dist[node] = 0;
ord.push(node);
std::vector<int> p(n,-1);
while (ord.size()) {
auto cur = ord.front();
ord.pop();
for (const auto& nei : gr[cur]) {
if (dist[nei] > 1 + dist[cur]) {
dist[nei] = 1 + dist[cur];
p[nei] = cur;
ord.push(nei);
}
}
}
it = std::max_element(dist.begin(),dist.end());
int node2 = std::distance(dist.begin(), it);
// node and node2 are two leaves that make up endpoints of diameter
std::vector<int> me(n, -1);
std::vector<char> ondiam(n,false);
for (int cur = node2; cur != -1; cur = p[cur]) {
ondiam[cur] = true;
}
std::function<void(int,int)> go = [&](int cur, int prev) {
for (const auto& nei : gr[cur]) {
if (nei == prev) continue;
if (ondiam[nei]) continue;
me[nei] = me[cur] + 1;
go(nei, cur);
}
};
int cur = node2, dnode2 = 0, dnode = dist[node2];
while (cur != -1) {
me[cur] = std::max(dnode2, dnode);
go(cur, -1);
dnode2++;
dnode--;
cur = p[cur];
}
int min = *std::min_element(me.begin(),me.end());
std::vector<int> ans;
for (int i = 0; i < n; ++i) {
if (me[i] == min)
ans.push_back(i);
}
return ans;
}
};