310. 最小高度树 --bfs(重点掌握)

对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。格式该图包含 n 个节点,标记为 0 到 n - 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边,...
摘要由CSDN通过智能技术生成

对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。

格式

该图包含 n 个节点,标记为 0 到 n - 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。

你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里。

示例 1:

输入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]

    0
    |
    1
   / \
  2   3 

输出: [1]
示例 2:

输入: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]

 0  1  2
  \ | /
    3
    |
    4
    |
    5 

输出: [3, 4]
说明:

根据树的定义,树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。

树的高度是指根节点和叶子节点之间最长向下路径上边的数量。

思路 拓扑序列 每次除去度为1 的节点 最后剩下的节点就是生成树的根节点

class Solution {
   
    public List<Integer> findMinHeightTrees(int n, int[][] edges) {
   
      List<Integer> ans = new ArrayList<Integer>();
      //建立一个 存放点信息的 list
      List<List<Integer>> map = new ArrayList<>();
         if (n == 1){
   
            ans.add(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据题意,我们可以使用分支限界法解决该问题,以下是对应的 Matlab 程序: ```matlab function [Vmin, Path] = circle_arrangement(R) n = length(R); Vmin = Inf; Path = []; % 初始化 ANode, AVal, ABound ANode = zeros(n+1, n); ANode(1,:) = 1:n; ANode(n+1,:) = 1; AVal = Inf * ones(1, n); AVal(1) = 0; ABound = zeros(1, n); for i = 1:n ABound(1) = ABound(1) + 2 * R(i); end while ~isempty(ANode) % 找到 AVal 中的最小值 [val, loc] = min(AVal); X = ANode(1:n, loc); k = ANode(n+1, loc); % 如果 ABound(loc) 小于 Vmin,进行扩展 if ABound(loc) < Vmin for i = setdiff(1:n, X(1:k)) if k < n % 计算 lb lb = ABound(loc) + 2 * R(i) + calc_bound(X, k+1, R); if lb < Vmin % 扩展节点 X(k+1) = i; ANode(:, end+1) = [X; k+1]; AVal(end+1) = AVal(loc) + calc_dist(X(k), i, R); ABound(end+1) = lb; end else % 计算当前价值 val = AVal(loc) + calc_dist(X(k), i, R) + R(i); if val < Vmin % 更新 Vmin 和 Path Vmin = val; Path = X; Path(k+1) = i; end end end end % 从 ANode, AVal, ABound 中删除 loc 对应的列/元素 ANode(:, loc) = []; AVal(loc) = []; ABound(loc) = []; end end % 计算代价函数 function bound = calc_bound(X, k, R) bound = 0; for i = 1:k for j = i+1:k bound = bound + calc_dist(X(i), X(j), R); end end end % 计算两圆心之间的距离 function dist = calc_dist(i, j, R) dist = sqrt((R(i) + R(j))^2 - (R(i) - R(j))^2); end ``` 具体来说,我们首先初始化 ANode、AVal 和 ABound。其中 ANode 是一个 n+1 行 m 列的矩阵,第一行到第 n 行分别记录了当前排列下每个圆的下标,第 n+1 行记录了当前已确定的圆的数量。AVal 是一个长度为 m 的数组,记录了每个节点的当前代价函数值。ABound 是一个长度为 m 的数组,记录了每个节点的下界(即代价函数的下界)。 我们使用类似于 BFS 的方式进行搜索。每次从 AVal 中找到最小值对应的节点,进行扩展。如果该节点的下界小于当前的 Vmin,我们对其进行扩展。扩展时,我们枚举下一个圆的下标,如果当前排列不是叶节点,我们计算该节点的下界 lb,如果 lb 小于 Vmin,就将该节点加入到 ANode 中,并更新对应的 AVal 和 ABound。如果当前排列是叶节点,我们计算该排列的代价函数值,如果小于 Vmin,就更新 Vmin 和 Path。最后从 ANode、AVal、ABound 中删除扩展过的节点即可。 其中,calc_bound 函数用于计算 X 的前 k 个圆的下标对应的排列的下界;calc_dist 函数用于计算第 i 个圆和第 j 个圆之间的距离。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值