由文件input.txt 给出输入数据,java实现Dijkstra算法
时间: 2024-03-15 09:45:36 浏览: 70
首先,我们需要读取文件input.txt中的输入数据。假设文件中的数据格式如下:
第一行为两个整数n和m,表示有n个节点和m条边。
接下来m行,每行三个整数u、v和w,表示从节点u到节点v有一条边,边权为w。
最后一行为一个整数s,表示起点。
我们可以使用Scanner类来读取文件中的数据。具体代码如下:
```java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Dijkstra {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(new File("input.txt"));
int n = scanner.nextInt(); // 节点数
int m = scanner.nextInt(); // 边数
List<int[]>[] graph = new ArrayList[n];
for (int i = 0; i < n; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < m; i++) {
int u = scanner.nextInt();
int v = scanner.nextInt();
int w = scanner.nextInt();
graph[u].add(new int[]{v, w});
graph[v].add(new int[]{u, w});
}
int s = scanner.nextInt(); // 起点
// TODO: 实现Dijkstra算法
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
```
接下来,我们需要实现Dijkstra算法。Dijkstra算法是一种单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。具体实现过程如下:
1. 创建一个数组dist,用于存储起点s到各个节点的最短距离。初始时,将dist[s]赋为0,其余元素赋为正无穷大。
2. 创建一个数组visited,用于记录节点是否已被访问。初始时,将visited[s]赋为true,其余元素赋为false。
3. 创建一个优先队列pq,用于存储待访问的节点。初始时,将起点s加入队列。
4. 从pq中取出距离起点s最近的节点u,将其标记为已访问。
5. 对于u的每个邻居节点v,如果v未被访问,则计算起点s到v的距离,并更新dist[v]的值。然后将v加入pq中。
6. 重复步骤4和5,直到pq为空。
具体实现代码如下:
```java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Dijkstra {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(new File("input.txt"));
int n = scanner.nextInt(); // 节点数
int m = scanner.nextInt(); // 边数
List<int[]>[] graph = new ArrayList[n];
for (int i = 0; i < n; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < m; i++) {
int u = scanner.nextInt();
int v = scanner.nextInt();
int w = scanner.nextInt();
graph[u].add(new int[]{v, w});
graph[v].add(new int[]{u, w});
}
int s = scanner.nextInt(); // 起点
int[] dist = new int[n]; // 存储起点s到各个节点的最短距离
boolean[] visited = new boolean[n]; // 记录节点是否已被访问
// 初始化dist数组
for (int i = 0; i < n; i++) {
dist[i] = Integer.MAX_VALUE;
}
dist[s] = 0;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]); // 优先队列
pq.offer(new int[]{s, 0});
while (!pq.isEmpty()) {
int[] curr = pq.poll();
int u = curr[0];
if (visited[u]) {
continue;
}
visited[u] = true;
for (int[] edge : graph[u]) {
int v = edge[0];
int w = edge[1];
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
pq.offer(new int[]{v, dist[v]});
}
}
}
// 输出结果
for (int i = 0; i < n; i++) {
System.out.printf("从节点%d到节点%d的最短距离为:%d\n", s, i, dist[i]);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
```
注意:本代码中使用了Java8的Lambda表达式来创建优先队列,需要使用Java8及以上版本的JDK才能编译运行。如果使用Java7或以下版本的JDK,可以使用匿名内部类来创建优先队列。
阅读全文