zoukankan      html  css  js  c++  java
  • 0310. Minimum Height Trees (M)

    Minimum Height Trees (M)

    题目

    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.

    Given a tree of n nodes labelled from 0 to n - 1, and an array of n - 1 edges where edges[i] = [ai, bi] indicates that there is an undirected edge between the two nodes ai and bi in the tree, you can choose any node of the tree as the root. When you select a node x as the root, the result tree has height h. Among all possible rooted trees, those with minimum height (i.e. min(h)) are called minimum height trees (MHTs).

    Return a list of all MHTs' root labels. You can return the answer in any order.

    The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

    Example 1:

    Input: n = 4, edges = [[1,0],[1,2],[1,3]]
    Output: [1]
    Explanation: As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT.
    

    Example 2:

    Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
    Output: [3,4]
    

    Example 3:

    Input: n = 1, edges = []
    Output: [0]
    

    Example 4:

    Input: n = 2, edges = [[0,1]]
    Output: [0,1]
    

    Constraints:

    • 1 <= n <= 2 * 10^4
    • edges.length == n - 1
    • 0 <= ai, bi < n
    • ai != bi
    • All the pairs (ai, bi) are distinct.
    • The given input is guaranteed to be a tree and there will be no repeated edges.

    题意

    在给定的无向无环图中确定一个根结点,使得得到的树的高度最小。

    思路

    从最外层的叶结点开始一层一层向里面“剥”,直到只剩最里面的1或2个结点即为答案。具体方法是:根据信息构建图,并把所有叶结点加入到队列中;依次出队,删去叶结点,更新叶结点连接的所有结点,并将新生成的叶结点入队;重复直到只剩1或2个结点。

    另一种可行的方法是,先求无向图的直径,即叶结点到叶结点的最长路径,再求这个路径中间的1或2个结点即为答案。求直径的具体方法:任选一个结点,用DFS/BFS找到离它最远的结点A,再从A出发,找到离A最远的结点B,A-B构成的路径即为直径。


    代码实现

    Java

    class Solution {
        public List<Integer> findMinHeightTrees(int n, int[][] edges) {
            if (n == 1) {
                return new ArrayList<Integer>() {
                    {
                        add(0);
                    }
                };
            }
          
            Map<Integer, Set<Integer>> g = new HashMap<>();
            Queue<Integer> q = new LinkedList<>();
    
            for (int i = 0; i < edges.length; i++) {
                int a = edges[i][0], b = edges[i][1];
                g.putIfAbsent(a, new HashSet<>());
                g.putIfAbsent(b, new HashSet<>());
    
                g.get(a).add(b);
                g.get(b).add(a);
            }
    
            for (int i = 0; i < n; i++) {
                if (g.get(i).size() == 1) {
                    q.offer(i);
                }
            }
    
            while (n > 2) {
                int size = q.size();
                for (int i = 0; i < size; i++) {
                    int x = q.poll();
                    for (int y : g.get(x)) {
                        g.get(y).remove(x);
                        if (g.get(y).size() == 1) {
                            q.offer(y);
                        }
                    }
                }
                n -= size;
            }
    
            return new ArrayList<>(q);
        }
    }
    
  • 相关阅读:
    NOIP 2016 提高组 复赛 Day2T1==洛谷2822 组合数问题
    Codevs 1710 == POJ 1190 生日蛋糕 == 洛谷P1731
    [网络流24题] COGS 750 栅格网络流
    [网络流24题] COGS 运输问题1
    狂K 线段树
    Graph coloring技能树
    智能体大赛酱油记
    graph coloring学习记录
    湖北省赛酱油记
    CCCC酱油记
  • 原文地址:https://www.cnblogs.com/mapoos/p/13929468.html
Copyright © 2011-2022 走看看