LeetCode Solutions

882. Reachable Nodes In Subdivided Graph

Time: $O(|E|\log |E|)$

Space: $O(|E|)$

			

class Solution {
 public:
  int reachableNodes(vector<vector<int>>& edges, int maxMoves, int n) {
    using P = pair<int, int>;
    vector<vector<P>> graph(n);
    priority_queue<P, vector<P>, greater<>> minHeap;  // (d, u)
    vector<int> dist(n, maxMoves + 1);

    for (const vector<int>& e : edges) {
      const int u = e[0];
      const int v = e[1];
      const int cnt = e[2];
      graph[u].emplace_back(v, cnt);
      graph[v].emplace_back(u, cnt);
    }

    minHeap.emplace(0, 0);
    dist[0] = 0;

    while (!minHeap.empty()) {
      const auto [d, u] = minHeap.top();
      minHeap.pop();
      // Already takes maxMoves to reach u, can't explore anymore
      if (dist[u] >= maxMoves)
        break;
      for (const auto& [v, w] : graph[u]) {
        const int newDist = d + w + 1;
        if (newDist < dist[v]) {
          dist[v] = newDist;
          minHeap.emplace(newDist, v);
        }
      }
    }

    const int reachableNodes =
        count_if(begin(dist), end(dist), [&](int d) { return d <= maxMoves; });
    int reachableSubnodes = 0;

    for (const vector<int>& e : edges) {
      const int u = e[0];
      const int v = e[1];
      const int cnt = e[2];
      // Reachable nodes of e from u
      const int a = dist[u] > maxMoves ? 0 : min(maxMoves - dist[u], cnt);
      // Reachable nodes of e from v
      const int b = dist[v] > maxMoves ? 0 : min(maxMoves - dist[v], cnt);
      reachableSubnodes += min(a + b, cnt);
    }

    return reachableNodes + reachableSubnodes;
  }
};
			

class Solution {
  public int reachableNodes(int[][] edges, int maxMoves, int n) {
    List<Pair<Integer, Integer>>[] graph = new List[n];
    Queue<int[]> minHeap = new PriorityQueue<>((a, b) -> a[0] - b[0]); // (d, u)
    int[] dist = new int[n];
    Arrays.fill(dist, maxMoves + 1);

    for (int i = 0; i < n; ++i)
      graph[i] = new ArrayList<>();

    for (int[] e : edges) {
      final int u = e[0];
      final int v = e[1];
      final int cnt = e[2];
      graph[u].add(new Pair<>(v, cnt));
      graph[v].add(new Pair<>(u, cnt));
    }

    minHeap.offer(new int[] {0, 0});
    dist[0] = 0;

    while (!minHeap.isEmpty()) {
      final int d = minHeap.peek()[0];
      final int u = minHeap.poll()[1];
      // Already takes maxMoves to reach u, can't explore anymore
      if (d >= maxMoves)
        break;
      for (Pair<Integer, Integer> node : graph[u]) {
        final int v = node.getKey();
        final int w = node.getValue();
        final int newDist = d + w + 1;
        if (newDist < dist[v]) {
          dist[v] = newDist;
          minHeap.offer(new int[] {newDist, v});
        }
      }
    }

    final int reachableNodes = (int) Arrays.stream(dist).filter(d -> d <= maxMoves).count();
    int reachableSubnodes = 0;

    for (int[] e : edges) {
      final int u = e[0];
      final int v = e[1];
      final int cnt = e[2];
      // Reachable nodes of e from u
      final int a = dist[u] > maxMoves ? 0 : Math.min(maxMoves - dist[u], cnt);
      // Reachable nodes of e from v
      final int b = dist[v] > maxMoves ? 0 : Math.min(maxMoves - dist[v], cnt);
      reachableSubnodes += Math.min(a + b, cnt);
    }

    return reachableNodes + reachableSubnodes;
  }
}
			

class Solution:
  def reachableNodes(self, edges: List[List[int]], maxMoves: int, n: int) -> int:
    graph = [[] for _ in range(n)]
    minHeap = [(0, 0)]  # (d, u)
    dist = [maxMoves + 1] * n
    dist[0] = 0

    for u, v, cnt in edges:
      graph[u].append((v, cnt))
      graph[v].append((u, cnt))

    while minHeap:
      d, u = heapq.heappop(minHeap)
      # Already takes maxMoves to reach u, can't explore anymore
      if dist[u] >= maxMoves:
        break
      for v, w in graph[u]:
        newDist = d + w + 1
        if newDist < dist[v]:
          dist[v] = newDist
          heapq.heappush(minHeap, (newDist, v))

    reachableNodes = sum(d <= maxMoves for d in dist)
    reachableSubnodes = 0

    for u, v, cnt in edges:
      # Reachable nodes of e from u
      a = 0 if dist[u] > maxMoves else min(maxMoves - dist[u], cnt)
      # Reachable nodes of e from v
      b = 0 if dist[v] > maxMoves else min(maxMoves - dist[v], cnt)
      reachableSubnodes += min(a + b, cnt)

    return reachableNodes + reachableSubnodes