|
| 1 | +package com.fishercoder.solutions.secondthousand; |
| 2 | + |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.Arrays; |
| 5 | +import java.util.List; |
| 6 | +import java.util.PriorityQueue; |
| 7 | + |
| 8 | +public class _1334 { |
| 9 | + public static class Solution1 { |
| 10 | + /** |
| 11 | + * Dijakstra's algorithm to find the shortest path from each node to all possibly reachable nodes within limit. |
| 12 | + * Keys to implement Dijkstra's algorithm: |
| 13 | + * 1. use an array to hold the shortest distance to each node for each node; |
| 14 | + * 2. initially, only the starting node distance is zero, all other nodes' distances to be infinity; |
| 15 | + * 3. use a PriorityQueue to poll out the next node that has the shortest distance and scan through all its neighbors, |
| 16 | + * if the cost can be updated, then put it into the priority queue |
| 17 | + */ |
| 18 | + public int findTheCity(int n, int[][] edges, int distanceThreshold) { |
| 19 | + List<List<int[]>> graph = new ArrayList(); |
| 20 | + int[][] shortestPaths = new int[n][n]; |
| 21 | + for (int i = 0; i < n; i++) { |
| 22 | + graph.add(new ArrayList<>()); |
| 23 | + } |
| 24 | + for (int[] edge : edges) { |
| 25 | + int source = edge[0]; |
| 26 | + int dest = edge[1]; |
| 27 | + int weight = edge[2]; |
| 28 | + graph.get(source).add(new int[]{dest, weight}); |
| 29 | + graph.get(dest).add(new int[]{source, weight}); |
| 30 | + } |
| 31 | + for (int i = 0; i < n; i++) { |
| 32 | + dijkstraAlgo(graph, i, shortestPaths[i]); |
| 33 | + } |
| 34 | + return findCity(shortestPaths, distanceThreshold); |
| 35 | + } |
| 36 | + |
| 37 | + private int findCity(int[][] shortestPaths, int distanceThreshold) { |
| 38 | + int ans = 0; |
| 39 | + int fewestConnected = shortestPaths.length; |
| 40 | + for (int i = 0; i < shortestPaths.length; i++) { |
| 41 | + int reachable = 0; |
| 42 | + for (int j = 0; j < shortestPaths[0].length; j++) { |
| 43 | + if (i != j && shortestPaths[i][j] <= distanceThreshold) { |
| 44 | + reachable++; |
| 45 | + } |
| 46 | + } |
| 47 | + if (reachable <= fewestConnected) { |
| 48 | + fewestConnected = reachable; |
| 49 | + ans = i; |
| 50 | + } |
| 51 | + } |
| 52 | + return ans; |
| 53 | + } |
| 54 | + |
| 55 | + private void dijkstraAlgo(List<List<int[]>> graph, int startCity, int[] shortestPath) { |
| 56 | + Arrays.fill(shortestPath, Integer.MAX_VALUE); |
| 57 | + shortestPath[startCity] = 0; |
| 58 | + PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> a[1] - b[1]); |
| 59 | + minHeap.offer(new int[]{startCity, 0}); |
| 60 | + while (!minHeap.isEmpty()) { |
| 61 | + int[] curr = minHeap.poll(); |
| 62 | + int currCity = curr[0]; |
| 63 | + int currCost = curr[1]; |
| 64 | + if (currCost > shortestPath[currCity]) { |
| 65 | + continue; |
| 66 | + } |
| 67 | + for (int[] neighbor : graph.get(currCity)) { |
| 68 | + int neighborCity = neighbor[0]; |
| 69 | + int neighborCost = neighbor[1]; |
| 70 | + if (currCost + neighborCost < shortestPath[neighborCity]) { |
| 71 | + shortestPath[neighborCity] = currCost + neighborCost; |
| 72 | + minHeap.offer(new int[]{neighborCity, shortestPath[neighborCity]}); |
| 73 | + } |
| 74 | + } |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + } |
| 79 | +} |
0 commit comments