经典题,需要温习。
题目链接:点击这里
总体思路
- 此题是网络结构,好久没做过这种题了。需要注意的是,这里有n个点,只有n-1条边,一定是无环图。因此,此题是无根树。
- 处理无根树比较麻烦,我们只知道一台server的编号,可以从这个server出发进行DFS,找到在其k距离范围内能达到的叶子节点(client)。但接下来怎么做呢?如何找到剩余叶子节点的最小server数呢?
- 因此,可以将无根树转化为有根数,就把server当作根节点,第一次DFS找到可以到达的所有叶子节点,然后从深度最深的叶子节点出发,找到其k祖先,将其设置为server,很容易证明这样是最省的。
代码实现
- 思路不是很难想,但代码上需要有些技巧。
树的构建
- 我们知道,可以使用邻接矩阵来构建,但在无向图中太浪费空间,并且此题n最大可以去1000,会造成内存溢出。
- 因此我们可以采用邻接链表的形式,由于此题只有编号没有其他信息,因此可构建树
vector<int> nodes[maxn]
; - 如何快速的找到其k个祖先呢?这里使用了一个数组进行存储其父节点,需要注意的是,由于此题是无向图,因此要注意方向,不然会造成死循环。
示例代码
由于深度不超过k的叶子节点已经被服务器覆盖了,因此我们存储深度的时候,只存储深度大于k的节点,使用DFS来覆盖。
#include <iostream> #include <vector> #in