Find the City With the Smallest Number of Neighbors at a Threshold Distance

There are n cities numbered from 0 to n-1. Given the array edges where edges[i] = [fromi, toi, weighti] represents a bidirectional and weighted edge between cities fromi and toi, and given the integer distanceThreshold.

Return the city with the smallest number of cities that are reachable through some path and whose distance is at most distanceThreshold, If there are multiple such cities, return the city with the greatest number.

Notice that the distance of a path connecting cities i and j is equal to the sum of the edges' weights along that path.

Example 1:

Input: n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
Output: 3
Explanation: The figure above describes the graph. 
The neighboring cities at a distanceThreshold = 4 for each city are:
City 0 -> [City 1, City 2] 
City 1 -> [City 0, City 2, City 3] 
City 2 -> [City 0, City 1, City 3] 
City 3 -> [City 1, City 2] 
Cities 0 and 3 have 2 neighboring cities at a distanceThreshold = 4, but we have to return city 3 since it has the greatest number.

思路:dijkstra algorithm,tricky的地方还是visited不能直接加入visited,要用pop的来判断;否则失去最优解; 对于1个node是ElogV, 那么所有node就是VElogV, 由于E ~ V2, 那么这题就是V3logV.

class Solution {
    private class Node {
        public int cost;
        public int city;
        public Node(int city, int cost) {
            this.cost = cost;
            this.city = city;
        }
    }
    
    private class NodeComparator implements Comparator<Node> {
        @Override
        public int compare(Node a, Node b) {
            if(a.cost != b.cost) {
                return b.cost - a.cost;
            } else {
                return b.city - a.city;
            }
        }
    } 
    
    public int findTheCity(int n, int[][] edges, int distanceThreshold) {
        if(edges == null || edges.length == 0 || edges[0].length == 0) {
            return -1;
        }
        // build graph
        HashMap<Integer, HashMap<Integer, Integer>> graph = new HashMap<Integer, HashMap<Integer, Integer>>();
        for(int i = 0; i < n; i++) {
            graph.putIfAbsent(i, new HashMap<Integer, Integer>());
        }
        
        for(int i = 0; i < edges.length; i++) {
            int from = edges[i][0];
            int to = edges[i][1];
            int cost = edges[i][2];
            graph.get(from).put(to, cost);
            graph.get(to).put(from, cost);
        }
        
        // find adjectent list for each city;
        HashMap<Integer, HashSet<Integer>> nodeAdjMap 
            = new HashMap<Integer, HashSet<Integer>>();
        // return minsize city number;
        int minsize = n ;
        int maxnode = -1;
        
        for(int i = 0; i < n; i++) {
            Queue<Node> queue = new PriorityQueue<Node>(new NodeComparator());
            HashSet<Integer> visited = new HashSet<Integer>();
            queue.offer(new Node(i, distanceThreshold));
            int count = 0;
            
            while(!queue.isEmpty()) {
                Node node = queue.poll();
                int city = node.city;
                int cost = node.cost;
                if(!visited.contains(city)) {
                    visited.add(city);
                    count++;
                }
                HashMap<Integer, Integer> neighborsMap = graph.get(city);
                if(!neighborsMap.isEmpty()) {
                    for(Integer neighbor: neighborsMap.keySet()) {
                        if(cost - neighborsMap.get(neighbor) >= 0) {
                            if(!visited.contains(neighbor)) {
                                queue.offer(new Node(neighbor, cost - neighborsMap.get(neighbor)));
                            }
                        }
                    }
                }
            }
            
            if(count <= minsize) {
                minsize = count;
                maxnode = i;
            }
        }
        return maxnode;
    }
}

思路2 用floyd-warshall算法 dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); time complexity: O(V^3)

class Solution {
    public int findTheCity(int n, int[][] edges, int distanceThreshold) {
        int[][] dis = new int[n][n];
        int res = 0;
        int smallcount = n;
        
        for(int[] row: dis) {
            Arrays.fill(row, 10000);
        }
        
        for(int[] e: edges) {
            dis[e[0]][e[1]] = dis[e[1]][e[0]] = e[2];
        }
        
        for(int i = 0; i < n; i++) {
            dis[i][i] = 0;
        }
        
        for(int k = 0; k < n; k++) {
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    dis[i][j] = Math.min(dis[i][j], dis[i][k] + dis[k][j]);
                }
            }
        }
        
        for(int i = 0; i < n; i++) {
            int count = 0;
            for(int j = 0; j < n; j++) {
                if(dis[i][j] <= distanceThreshold) {
                    count++;
                }
            }
            if(count <= smallcount) {
                smallcount = count;
                res = i;
            }
        }
        return res;
    }
}
发布了663 篇原创文章 · 获赞 13 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/u013325815/article/details/104558369
今日推荐