2022-6-20 真题练习-图-Dijkstra算法
作者:互联网
MT17 共享单车
校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,而非本地IDE。
描述
给出一张图,图上有 n 个节点,从 1 到 n 编号,和 m 条边,每条边有一个权重,表示小明走路通过这条边的时间,所有边都是无向的。
小明从 1 号节点出发,他要去 n 号节点,他想用的总时间尽可能的短。小明有共享单车 APP ,图上有些节点有共享单车,当他到达一个有车节点后,他就可以一直骑车,如果一条边走路通过的时间是 t ,那么骑车通过的时间就是 t/2 ,这里的除法是向下取整,如 t = 1 时 t/2 = 0,t = 2时,t/2 = 1。 小明可以先走到一个节点取车再骑车过去,也可以直接走过去,问他在最优策略下,需要多少时间从 1 到 n。 数据范围: 1 \le n,m \le 10^5 ,\1≤n,m≤105, 1 \le u,v \le n ,1 \le w \le 10^9 ,0 \le k \le n\1≤u,v≤n,1≤w≤109,0≤k≤n输入描述:
第一行两个数 n,m ,接下来有 m 行,每行三个数 u,v,w ,表示 u 和 v 之间有一条边权为 w 的无向边 接下来一个数 k ,表示有 k 个节点有车,最后输入 k 行,表示有车节点的编号 输入的图中可能有自环和重边输出描述:
输出一个数,从 1 到 n 的最少所需的时间,如果 1 和 n 不连通,输出 -11 import java.util.*; 2 public class Main{ 3 static class Eage{ 4 int next; 5 int w; 6 Eage(int n,int w1){ 7 next=n; 8 w=w1; 9 } 10 } 11 12 static class State{ 13 int node; 14 long dist; 15 int hasBike; 16 State(int n,long d,int h){ 17 node=n; 18 dist=d; 19 hasBike=h; 20 } 21 } 22 public static void main(String[] args) { 23 Scanner sc = new Scanner(System.in); 24 int n = sc.nextInt(); 25 int m = sc.nextInt(); 26 List<List<Eage>> w=new ArrayList<>(); 27 for (int i=0;i<n+1;i++) w.add(new ArrayList<>()); 28 for (int i=0;i<m;i++){ 29 int u=sc.nextInt(); 30 int v=sc.nextInt(); 31 int weight=sc.nextInt(); 32 if (u!=v){ 33 w.get(u).add(new Eage(v,weight)); 34 w.get(v).add(new Eage(u,weight)); 35 } 36 } 37 Set<Integer> bike=new HashSet<>(); 38 int k=sc.nextInt(); 39 for (int i=0;i<k;i++){ 40 int temp=sc.nextInt(); 41 bike.add(temp); 42 } 43 PriorityQueue<State> queue=new PriorityQueue<>(new Comparator<State>() { 44 @Override 45 public int compare(State o1, State o2) { 46 if (o1.dist>o2.dist) return 1; 47 return -1; 48 } 49 }); 50 // int[] 信息分别代表 当前节点,当前时间,是否有车 51 long[][] dis=new long[2][n+1]; 52 Arrays.fill(dis[0],Long.MAX_VALUE); 53 Arrays.fill(dis[1],Long.MAX_VALUE); 54 int tmp=bike.contains(1)?1:0; 55 dis[tmp][1]=0; 56 long distance=0L; 57 queue.offer(new State(1,0,tmp)); 58 while (!queue.isEmpty()){ 59 State cur=queue.poll(); 60 int curNode=cur.node; 61 long curDis=cur.dist; 62 int hasBike=cur.hasBike; 63 64 for (Eage x:w.get(curNode)){ 65 66 if (hasBike==0){ 67 distance=curDis+x.w; 68 }else{ 69 distance=curDis+x.w/2; 70 } 71 int has=hasBike; 72 if (bike.contains(x.next)){ 73 has=1; 74 } 75 if (distance<dis[has][x.next]){ 76 dis[has][x.next]=distance; 77 queue.offer(new State(x.next,distance,has)); 78 } 79 } 80 } 81 if (Math.min(dis[0][n],dis[1][n])==Long.MAX_VALUE){ 82 System.out.println(-1); 83 }else{ 84 System.out.println(Math.min(dis[0][n],dis[1][n])); 85 } 86 87 } 88 }
思路:利用Dijkstra算法计算起点到其他点的距离,有单车的存在,增加一个维度。
标签:le,20,真题,int,State,hasBike,Dijkstra,new,节点 来源: https://www.cnblogs.com/benbicao/p/16394793.html