📜  给定非循环图的每个深度处的最小元素之和(1)

📅  最后修改于: 2023-12-03 15:41:17.947000             🧑  作者: Mango

给定非循环图的每个深度处的最小元素之和

问题描述

给定一个非循环图,每个节点都有一个权重。 请你编写一个程序来计算图的每个深度处的最小元素的权重之和。深度表示从起点出发到达该节点的最短路径长度。 注意:节点权重为正整数,且不会超过 100000。

解决方案

我们可以使用 BFS(广度优先搜索)来解决这个问题。从起点开始,依次遍历该节点的所有邻居节点,如果邻居节点没有被访问过,则将邻居节点加入队列,同时记录下该节点的权重和到达该节点的深度。

具体步骤如下:

  1. 创建一个队列,将起点节点加入队列;
  2. 创建一个数组,记录每个节点是否被访问过;
  3. 创建一个数组,记录每个节点到起点的最短路径长度;
  4. 创建一个数组,记录每个深度处的最小元素的权重之和;
  5. 从队列中取出一个节点,遍历该节点的所有邻居节点,如果邻居节点没有被访问过,则将邻居节点加入队列,并记录下该节点的权重和到达该节点的深度;
  6. 如果队列不为空,则回到第 5 步;否则,返回第 4 步记录的结果。

代码如下:

from collections import deque

def min_depth_sum(root):
    queue = deque([(root, 0)])
    visited = set([root])
    depth_sum = [0]
    depth_min = [float('inf')]
    
    while queue:
        node, depth = queue.popleft()
        if depth > len(depth_sum) - 1:
            depth_sum.append(0)
            depth_min.append(float('inf'))
        depth_sum[depth] += node.val
        depth_min[depth] = min(depth_min[depth], node.val)
        for neighbor in node.neighbors:
            if neighbor not in visited:
                queue.append((neighbor, depth+1))
                visited.add(neighbor)
    
    return sum(depth_min)

代码说明:

  1. 使用 deque 实现队列;
  2. 使用 visited 集合记录已经访问过的节点;
  3. 使用 depth_sum 数组记录每个深度处的节点权重之和;
  4. 使用 depth_min 数组记录每个深度处的最小元素权重;
  5. 在遍历节点的邻居节点时,需要将当前节点的深度加 1,同时将邻居节点加入队列,并标记为已经访问;
  6. 最后返回 depth_min 数组的权重之和。
示例

以如下图为例:

example_graph

执行代码:

node1 = Node(val=1)
node2 = Node(val=2)
node3 = Node(val=3)
node4 = Node(val=4)
node5 = Node(val=5)
node6 = Node(val=6)

node1.neighbors = [node2, node3]
node2.neighbors = [node1, node4, node5]
node3.neighbors = [node1, node6]
node4.neighbors = [node2]
node5.neighbors = [node2]
node6.neighbors = [node3]

print(min_depth_sum(node1)) # 7

结果为 7,理由如下:

  1. 节点 1 到起点的最短路径长度为 0,权重为 1;
  2. 节点 2 和 3 到起点的最短路径长度为 1,节点 2 的权重为 2,节点 3 的权重为 3,因此深度为 1 的最小元素权重为 2;
  3. 节点 4 和 5 到起点的最短路径长度为 2,节点 4 的权重为 4,节点 5 的权重为 5,因此深度为 2 的最小元素权重为 4;
  4. 节点 6 到起点的最短路径长度为 2,权重为 6,因此深度为 2 的最小元素权重为 4;
  5. 最后,深度 1 和深度 2 的最小元素权重之和为 2+4=6,加上起点的权重(1),结果为 7。