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.
Key point:
1. graph ->HashMap<Integer, List<Node>>; 
2. 每个点,作为起点,cost是distanceThreshold开始往外走;走一步,下一node cost减去weight,加入pq,这样每次都是走最大的cost,这样得到的node数目最小;

class Solution {
    private class Node {
        public int city;
        public int cost;
        public Node (int city, int cost) {
            this.city = city;
            this.cost = cost;
        }
    }
    
    public int findTheCity(int n, int[][] edges, int distanceThreshold) {
        if(edges == null || edges.length == 0 || edges[0].length == 0) {
            return -1;
        }
        
        HashMap<Integer, List<Node>> graph = new HashMap<>();
        for(int[] edge: edges) {
            int from = edge[0];
            int to = edge[1];
            int weight = edge[2];
            graph.putIfAbsent(from, new ArrayList<Node>());
            graph.putIfAbsent(to, new ArrayList<Node>());
            graph.get(from).add(new Node(to, weight));
            graph.get(to).add(new Node(from, weight));
        }
        
        int maxnode = -1;
        int minsize = n;
        
        for(int i = 0; i < n; i++) {
            PriorityQueue<Node> pq = new PriorityQueue<Node>((a, b) -> {
                if(a.cost != b.cost) {
                    return b.cost - a.cost;
                } else {
                    return b.city - a.city;
                }
            });
            
            pq.offer(new Node(i, distanceThreshold));
            HashSet<Integer> visited = new HashSet<>();
            int count = 0;
            
            while(!pq.isEmpty()) {
                Node node = pq.poll();
                if(visited.contains(node.city)) {
                    continue;
                }
                visited.add(node.city);
                count++;
                if(graph.containsKey(node.city)) {
                    for(Node neighbor: graph.get(node.city)) {
                        if(!visited.contains(neighbor.city )){
                            if(node.cost - neighbor.cost >= 0) {
                              pq.offer(new Node(neighbor.city, node.cost - neighbor.cost));  
                            }
                        }
                    }
                }
            }
            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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值