LeetCode 题解工作台

细分图中的可到达节点

给你一个无向图( 原始图 ),图中有 n 个节点,编号从 0 到 n - 1 。你决定将图中的每条边 细分 为一条节点链,每条边之间的新节点数各不相同。 图用由边组成的二维数组 edges 表示,其中 edges[i] = [u i , v i , cnt i ] 表示原始图中节点 u i 和 v …

category

3

题型

code_blocks

4

代码语言

hub

3

相关题

当前训练重点

困难 ·

bolt

答案摘要

这道题本质是求从节点 出发,最多经过 步,可以到达多少个节点。单源最短路,且边权非负,我们可以考虑使用 Dijkstra 算法。 根据题目描述,节点 到节点 之间存在 个新节点,那么节点 到节点 的距离为 $cnt_i + 1$。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 堆 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个无向图(原始图),图中有 n 个节点,编号从 0n - 1 。你决定将图中的每条边 细分 为一条节点链,每条边之间的新节点数各不相同。

图用由边组成的二维数组 edges 表示,其中 edges[i] = [ui, vi, cnti] 表示原始图中节点 ui 和 vi 之间存在一条边,cnti 是将边 细分 后的新节点总数。注意,cnti == 0 表示边不可细分。

细分[ui, vi] ,需要将其替换为 (cnti + 1) 条新边,和 cnti 个新节点。新节点为 x1, x2, ..., xcnti ,新边为 [ui, x1], [x1, x2], [x2, x3], ..., [xcnti-1, xcnti], [xcnti, vi]

现在得到一个 新的细分图 ,请你计算从节点 0 出发,可以到达多少个节点?如果节点间距离是 maxMoves 或更少,则视为 可以到达

给你原始图和 maxMoves ,返回 新的细分图中从节点 0 出发 可到达的节点数 。

 

示例 1:

输入:edges = [[0,1,10],[0,2,1],[1,2,2]], maxMoves = 6, n = 3
输出:13
解释:边的细分情况如上图所示。
可以到达的节点已经用黄色标注出来。

示例 2:

输入:edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], maxMoves = 10, n = 4
输出:23

示例 3:

输入:edges = [[1,2,4],[1,4,5],[1,3,1],[2,3,4],[3,4,5]], maxMoves = 17, n = 5
输出:1
解释:节点 0 与图的其余部分没有连通,所以只有节点 0 可以到达。

 

提示:

  • 0 <= edges.length <= min(n * (n - 1) / 2, 104)
  • edges[i].length == 3
  • 0 <= ui < vi < n
  • 图中 不存在平行边
  • 0 <= cnti <= 104
  • 0 <= maxMoves <= 109
  • 1 <= n <= 3000
lightbulb

解题思路

方法一:Dijkstra 算法

这道题本质是求从节点 00 出发,最多经过 maxMovesmaxMoves 步,可以到达多少个节点。单源最短路,且边权非负,我们可以考虑使用 Dijkstra 算法。

根据题目描述,节点 uiu_i 到节点 viv_i 之间存在 cnticnt_i 个新节点,那么节点 uiu_i 到节点 viv_i 的距离为 cnti+1cnt_i + 1

我们举个简单的例子,以下节点 11 和节点 22 之间存在 33 个新节点,那么节点 11 到节点 22 之间有 44 条边,也即距离为 44

1 -- o -- o -- o -- 2

因此,我们可以将原图中两点之间新节点的个数 cnticnt_i11,得到两点之间的距离。然后构建一个邻接表 gg,用于存储每个节点的邻接节点以及到达邻接节点的距离。

接下来,我们使用 Dijkstra 算法求出从节点 00 到原始图其余所有节点的最短距离,存储在数组 distdist 中。

然后,我们遍历数组 distdist,统计其中小于等于 maxMovesmaxMoves 的节点个数,也就是我们可以到达的节点数。不过,这并不是最终答案,我们还需要加上新节点中符合条件的节点个数。

我们可以发现,如果我们能在 dist[u]dist[u] 步到达节点 uu(其中 dist[u]maxMovesdist[u] \leq maxMoves),并且节点 uu 到节点 vv 之间有 cntcnt 个新节点,那么我们能通过节点 uu 到达的新节点个数 a=min(cnt,maxMovesdist[u])a=\min(cnt, maxMoves - dist[u])。同理,我们能通过节点 vv 到达的新节点个数 b=min(cnt,maxMovesdist[v])b=\min(cnt, maxMoves - dist[v])。那么,我们能到达节点 uu 和节点 vv 之间的新节点个数为 min(cnt,a+b)\min(cnt, a + b)

因此,我们再遍历所有的边,统计其中能到达的新节点个数,累加到答案中即可。

时间复杂度 O(n+m×logn)O(n + m \times \log n),其中 mmnn 分别为边数和节点数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution:
    def reachableNodes(self, edges: List[List[int]], maxMoves: int, n: int) -> int:
        g = defaultdict(list)
        for u, v, cnt in edges:
            g[u].append((v, cnt + 1))
            g[v].append((u, cnt + 1))
        q = [(0, 0)]
        dist = [0] + [inf] * n
        while q:
            d, u = heappop(q)
            for v, cnt in g[u]:
                if (t := d + cnt) < dist[v]:
                    dist[v] = t
                    q.append((t, v))
        ans = sum(d <= maxMoves for d in dist)
        for u, v, cnt in edges:
            a = min(cnt, max(0, maxMoves - dist[u]))
            b = min(cnt, max(0, maxMoves - dist[v]))
            ans += min(cnt, a + b)
        return ans
speed

复杂度分析

指标
时间O(E \log N)
空间O(E)
psychology

面试官常问的追问

外企场景
  • question_mark

    Understanding graph traversal techniques and shortest path algorithms is key to solving this problem effectively.

  • question_mark

    Look for familiarity with heaps or priority queues, as they are essential for managing the node traversal efficiently.

  • question_mark

    The ability to handle edge transformations and correctly manage graph subdivisions will signal strong problem-solving skills.

warning

常见陷阱

外企场景
  • error

    Mismanaging edge subdivisions can lead to incorrect graph representations, making it hard to track reachable nodes.

  • error

    Overcomplicating the algorithm or using inefficient traversal techniques can result in suboptimal performance, especially with larger graphs.

  • error

    Failure to properly account for the move limit and correctly implementing the priority queue could lead to incorrect answers.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Increase the size of the graph and test how well the algorithm scales for larger input sizes.

  • arrow_right_alt

    Add restrictions on the maximum number of new nodes that can be added for each edge, impacting the complexity of the transformation.

  • arrow_right_alt

    Change the traversal rule to consider different starting nodes, altering the reachability calculation.

help

常见问题

外企场景

细分图中的可到达节点题解:堆 | LeetCode #882 困难