编程语言
首页 > 编程语言> > 2022-6-20 真题练习-图-Dijkstra算法

2022-6-20 真题练习-图-Dijkstra算法

作者:互联网

MT17 共享单车   warning 校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,而非本地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 不连通,输出 -1
 1 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