本此選做的題目是有關於圖與樹的應用Minimum Height Trees,大致的要求如下
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]
vector<unordered_set<int>> v(n);
for(int i = 0; i < edges.size();++i)
{
v[edges[i].first].insert(edges[i].second);
v[edges[i].second].insert(edges[i].first);
}
vector<int> ans;
if(!n)
return ans;
if(n == 1)
{
ans.push_back(0);
}
關於樹的遍歷已經最小樹的根可以透過寬度搜索(BFS)來實現,透過由下往上的遍歷,具體實現如下,首先先確定鏈表中size()為1的頂點,因為這些點頂可以確定是樹葉
vector<int> leaves;
for(int i = 0; i < n; ++i)
if(v[i].size() == 1)
leaves.push_back(i);
接著是BFS的實現,由樹葉往上搜索,先便利樹葉所有鄰近的頂點,並先刪除樹葉,如果在樹葉刪除之後,新琳的點的size為1的話,那確認他是新的樹葉將他加入newleaves中,在下次循環中再以相同的方法檢測,此外,當我們沒有檢測到新的newleaves時,意味者當前的leaves克能是構成最短樹的根結點。
while(true)
{
vector<int> newleaves;
for(int l : leaves)
{
for(int i : v[l])
{
v[i].erase(l);
if(v[i].size() == 1)
newleaves.push_back(i);
}
}
if(newleaves.size() == 0)
return leaves;
leaves = newleaves;
}