There are n cities connected by m flights. Each fight starts from city u and arrives at v with a price w.
Now given all the cities and fights, together with starting city src and the destination dst, your task is to find the cheapest price from src to dst with up to k stops. If there is no such route, output -1.
class Solution { public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) { int[] costs=new int[n]; Arrays.fill(costs,Integer.MAX_VALUE); costs[src]=0; for(int i=0;i<=K;i++){ int[] temp=Arrays.copyOf(costs,n); for(int[] f:flights){ int current=f[0], next=f[1],addcost=f[2]; if(costs[current]==Integer.MAX_VALUE) continue; temp[next]=Math.min(temp[next],costs[current]+addcost);//这里要注意是temp还是costs } costs=temp; } return costs[dst]==Integer.MAX_VALUE?-1:costs[dst]; } }
这是leetcode上看到的别人提交的一段代码,非常简洁,也不需要用map之类,解题基本思想还是
DijKstra,但比较容易出错,用bfs,最大的循环是记录bfs的路径长度,每次从每个点向外延伸1步,更新状态,第二层循环是对于图的整个连接方式每次全部循环一遍,看向外延伸是否能更新图的状态。主要是在注释行容易弄混。
DijKstra需要注意的问题是,每一步中都需要一个temp数组去存这一步更新前的状态,因为在遍历所有边并更新图的过程中,会把一些节点的值改变,如果没有一个数组去存初始状态,后遍历到的点基于的值可能是先遍历到的点已经进行了更新的值,那就不再是这一步的bfs了。要注意的是,这种方法中,每次遍历会有一些重复的操作,就是对于之前的步骤里已经更新过的操作还会之后每轮再走一遍,所以注释行需要和更新一步比较的对象是更新后的矩阵中该点的cost,避免更新的值被之前的值冲掉。在更新过程中,同一个点可能会被不同路径过来的情况不断更新,我们需要一个这所有路径中的最小值,所以应该是和temp数组中该点的值进行比较(可能已经被更新过了)。
还可以用priorityqueue,每个节点里存入cost, layer数,点的名称,比较有技巧性,自己对于priorityqueue非常不熟悉,这个解法可以学习一下。
class Solution { public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) { Map<Integer,Map<Integer,Integer>> map=new HashMap<>(); for(int[] flight:flights){ if(!map.containsKey(flight[0])) map.put(flight[0],new HashMap<>()); map.get(flight[0]).put(flight[1],flight[2]); } PriorityQueue<int[]> pq=new PriorityQueue<>((a,b)->(Integer.compare(a[0],b[0]))); pq.offer(new int[]{0,src,K+1}); while(!pq.isEmpty()){ int[] temp=pq.poll(); if(temp[1]==dst) return temp[0]; if(temp[2]>0){ Map<Integer,Integer> tinymap=map.get(temp[1]); if(tinymap==null) continue; for(int a:tinymap.keySet()){ pq.offer(new int[]{temp[0]+tinymap.get(a),a,temp[2]-1}); } } } return -1; } }
浙公网安备 33010602011771号