题目描述
一个局域网内有很多台电脑,分别标注为 0 ~ N-1 的数字。相连接的电脑距离不一样,所以感染时间不一样,感染时间用 t 表示。
其中网络内一台电脑被病毒感染,求其感染网络内所有的电脑最少需要多长时间。如果最后有电脑不会感染,则返回-1。
给定一个数组 times 表示一台电脑把相邻电脑感染所用的时间。
如图:path[i] = {i, j, t} 表示:电脑 i->j,电脑 i 上的病毒感染 j,需要时间 t。
输入描述
4
3
2 1 1
2 3 1
3 4 1
2
输出描述
2
用例1
输入
4
3
2 1 1
2 3 1
3 4 1
2
输出
2
说明
第一个参数:局域网内电脑个数N,1 ≤ N ≤ 200;第二个参数:总共多少条网络连接第三个 2 1 1 表示2->1时间为1第六行:表示病毒最开始所在电脑号2
代码
package odjava;import java.util.*;public class 三_电脑病毒感染 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 读取节点数和边数int n = sc.nextInt(); // 节点数int m = sc.nextInt(); // 边数// 创建邻接表来表示图HashMap<Integer, ArrayList<int[]>> graph = new HashMap<>();// 读取边的信息并构建邻接表for (int i = 0; i < m; i++) {int u = sc.nextInt(); // 出发点int v = sc.nextInt(); // 目标点int w = sc.nextInt(); // 出发点到达目标点的耗时// 添加边到邻接表graph.putIfAbsent(u, new ArrayList<>());graph.get(u).add(new int[]{v, w});}// 记录源点到其他节点的最短耗时int[] dist = new int[n + 1];// 初始化源点到其他节点的最短耗时为无穷大Arrays.fill(dist, Integer.MAX_VALUE);// 源点的编号int src = sc.nextInt();// 源点到自身的最短耗时为0dist[src] = 0;// 创建优先队列,用于存储待探索的节点// 优先队列中节点的优先级按照其到源点的距离排序,距离越小优先级越高PriorityQueue<Integer> needCheck = new PriorityQueue<>((a, b) -> dist[a] - dist[b]);// 将源点加入优先队列needCheck.add(src);// 记录节点是否已经被访问过boolean[] visited = new boolean[n + 1];visited[src] = true;// 进行 Dijkstra 算法的核心步骤,找到源点到其他节点的最短路径while (!needCheck.isEmpty()) {// 取出当前最短距离的节点int cur = needCheck.poll();visited[cur] = false;// 遍历当前节点的所有邻居节点if (graph.containsKey(cur)) {for (int[] next : graph.get(cur)) {int v = next[0]; // 邻居节点编号int w = next[1]; // 当前节点到邻居节点的边的权重// 计算从源点经当前节点到达邻居节点的距离int newDist = dist[cur] + w;// 如果新距离比之前记录的距离要小,则更新距离并加入优先队列if (newDist < dist[v]) {dist[v] = newDist; // 更新距离if (!visited[v]) {// 如果邻居节点不在优先队列中,则将其加入队列visited[v] = true;needCheck.add(v);}}}}}// 找到源点到其他节点的最大耗时,即最长路径int maxTime = 0;for (int i = 1; i <= n; i++) {maxTime = Math.max(maxTime, dist[i]);}// 如果存在无法到达的节点,则输出 -1;否则输出最大耗时System.out.println(maxTime == Integer.MAX_VALUE ? -1 : maxTime);}
}