849. Dijkstra求最短路 Java代码 (dijkstra朴素版)

32 篇文章 1 订阅

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

算法思路:

dijkstra算法是求单源最短路问题的算法,即从某个固定的点到图中其余任一点的最短路。需要满足图中的权值均为正值,无负权。朴素版的dijkstra又要求图为稠密图,即图中的点数与边数的平方成正比,时间复杂度为O(n^2),其中n表示图中点数。

朴素dijkstra算法步骤:(一初二迭三找四更)

  1. 初始化dis,除源点到源点dis为0外,源点到其余点均无通路
  2. 迭代n条边
  3. 找当前没有被更新过的点的距离的最小值的点t
  4. 借助点t更新其它点的最短距离

存储方式:邻接矩阵

Java代码:

import java.io.*;
import java.util.Arrays;

public class Main {
	static int n, m;
	static int N = 510;
	static final int INF = 0x3f3f3f3f; // 没有路径
	static int [][]g = new int[N][N];
	static boolean []vis = new boolean [N]; // 当前已经确定最短路距离的点(已经用该点更新过其它点)
	static int []dis = new int[N];  // 从源点到其余点的最短距离
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] split = br.readLine().split(" ");
		n = Integer.parseInt(split[0]);
		m = Integer.parseInt(split[1]);
		
		for(int i = 1; i <= n; i++)
			Arrays.fill(g[i], INF);
		
		for(int i = 0; i < m; i++) {
			split = br.readLine().split(" ");
			int a = Integer.parseInt(split[0]);
			int b = Integer.parseInt(split[1]);
			int w = Integer.parseInt(split[2]);
			g[a][b] = Math.min(g[a][b], w);  // 处理重边,重边时,选取最短距离
		}
		
		System.out.println(dijkstra());
	}
	
	public static int dijkstra() {
		Arrays.fill(dis, INF);  // 1.初始化dis,除源点到源点dis为0外,源点到其余点均无通路
		dis[1] = 0;
		
		for(int i = 0; i < n; i++) {  // 2.迭代n条边
			
			int t = -1;
			for(int j = 1; j <= n; j++)  // 3.找当前没有被更新过的点的距离的最小值的点t
				if(!vis[j] && (t == -1 || dis[j] < dis[t]))
					t = j;
			vis[t] = true;
			
			for(int j = 1; j <= n; j++) {  // 4.借助点t更新其它点的最短距离
				dis[j] = Math.min(dis[j], dis[t] + g[t][j]);
			}
		}
		
		if(dis[n] != INF) return dis[n]; 
		return -1;
	}
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当然可以,以下是一个使用堆优化的Dijkstra最短路径算法的Java代码: ``` import java.util.*; public class Dijkstra { static final int INF = Integer.MAX_VALUE; // 用来表示两个节点之间没有边相连的情况 int n; // 节点的个数 int[][] g; // 图的邻接矩阵 int[] dist; // 存储起点到各个节点的最短距离 boolean[] visited; // 判断一个节点是否已经被访问 PriorityQueue<Node> pq; // 用来存储未被访问的节点 public Dijkstra(int n) { this.n = n; g = new int[n][n]; dist = new int[n]; visited = new boolean[n]; pq = new PriorityQueue<>(n, new NodeComparator()); Arrays.fill(dist, INF); dist[0] = 0; // 假设起点为0 pq.offer(new Node(0, 0)); // 将起点加入到优先队列中 } // 添加一条从u到v权值为w的边 public void addEdge(int u, int v, int w) { g[u][v] = w; } // Dijkstra算法 public void dijkstra() { while (!pq.isEmpty()) { Node node = pq.poll(); int u = node.u; if (visited[u]) continue; visited[u] = true; for (int v = 0; v < n; v++) { if (g[u][v] != 0) { // 如果u和v之间有边相连 int newDist = dist[u] + g[u][v]; if (newDist < dist[v]) { // 更新最短距离 dist[v] = newDist; pq.offer(new Node(v, dist[v])); } } } } } // 输出起点到各个节点的最短距离 public void printDist() { for (int i = 0; i < n; i++) { System.out.println("dist[" + i + "] = " + dist[i]); } } // 节点类,用来存储节点的编号和距离 class Node { int u; int dist; public Node(int u, int dist) { this.u = u; this.dist = dist; } } // 节点比较器,用来比较节点之间的距离 class NodeComparator implements Comparator<Node> { public int compare(Node a, Node b) { return a.dist - b.dist; } } public static void main(String[] args) { Dijkstra dijkstra = new Dijkstra(6); dijkstra.addEdge(0, 1, 10); dijkstra.addEdge(0, 4, 15); dijkstra.addEdge(1, 2, 15); dijkstra.addEdge(1, 3, 2); dijkstra.addEdge(2, 5, 5); dijkstra.addEdge(3, 2, 1); dijkstra.addEdge(3, 5, 12 ### 回答2: 下面是用JAVA语言编写的堆优化的迪杰斯特拉最短路代码: ```java import java.util.*; public class DijkstraAlgorithm { private int V; private int[] dist; private Set<Integer> settled; private PriorityQueue<HeapNode> pq; private List<List<HeapNode>> adj; public DijkstraAlgorithm(int V) { this.V = V; dist = new int[V]; settled = new HashSet<>(); pq = new PriorityQueue<>(V, new HeapNode()); adj = new ArrayList<>(); for (int i = 0; i < V; i++) { dist[i] = Integer.MAX_VALUE; } } public void addEdge(int source, int destination, int weight) { List<HeapNode> list = new ArrayList<>(); list.add(new HeapNode(destination, weight)); adj.add(list); } public void dijkstraAlgorithm(int source) { pq.add(new HeapNode(source, 0)); dist[source] = 0; while (settled.size() != V) { int u = pq.remove().node; settled.add(u); exploreNeighbours(u); } } private void exploreNeighbours(int u) { int edgeDistance = -1; int newDistance = -1; for (int i = 0; i < adj.get(u).size(); i++) { HeapNode v = adj.get(u).get(i); if (!settled.contains(v.node)) { edgeDistance = v.cost; newDistance = dist[u] + edgeDistance; if (newDistance < dist[v.node]) { dist[v.node] = newDistance; } pq.add(new HeapNode(v.node, dist[v.node])); } } } public static void main(String[] args) { int V = 6; int source = 0; DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(V); dijkstra.addEdge(0, 1, 4); dijkstra.addEdge(0, 2, 2); dijkstra.addEdge(1, 3, 2); dijkstra.addEdge(1, 2, 5); dijkstra.addEdge(2, 3, 7); dijkstra.addEdge(3, 4, 2); dijkstra.addEdge(4, 0, 4); dijkstra.addEdge(4, 1, 4); dijkstra.addEdge(4, 5, 6); dijkstra.dijkstraAlgorithm(source); System.out.println("从源节点 " + source + " 到其他节点的最短距离为:"); for (int i = 0; i < dijkstra.dist.length; i++) { System.out.println(source + " 到 " + i + " 的最短距离为:" + dijkstra.dist[i]); } } } class HeapNode implements Comparator<HeapNode> { public int node; public int cost; public HeapNode() { } public HeapNode(int node, int cost) { this.node = node; this.cost = cost; } @Override public int compare(HeapNode node1, HeapNode node2) { if (node1.cost < node2.cost) { return -1; } if (node1.cost > node2.cost) { return 1; } return 0; } } ``` 该代码实现了堆优化的迪杰斯特拉最短路算法。在DijkstraAlgorithm类的构造函数中,我们初始化了dist数组和settled集合。然后,addEdge方法用于向邻接表添加边的信息。dijkstraAlgorithm方法是实际的算法实现,它从源节点开始,不断选择代价最小的节点,并更新与其相邻节点的最短距离。exploreNeighbours方法用于探索节点的邻居节点,并更新最短距离。最后,通过调用main方法,我们可以测试该算法并输出从源节点到其他节点的最短距离。 ### 回答3: 以下是使用Java代码实现堆优化的Dijkstra最短路径算法: ```java import java.util.Arrays; import java.util.PriorityQueue; public class Dijkstra { private int V; // 图中顶点的个数 private int source; // 源顶点的下标 private int[] dist; // 存储最短路径的距离 private boolean[] visited; // 记录顶点是否已被访问 private int[][] graph; // 图的邻接矩阵表示 public Dijkstra(int[][] graph, int source) { this.V = graph.length; this.source = source; this.dist = new int[V]; Arrays.fill(dist, Integer.MAX_VALUE); this.visited = new boolean[V]; Arrays.fill(visited, false); this.graph = graph; } // 查找最短路径 public void dijkstra() { dist[source] = 0; PriorityQueue<Node> pq = new PriorityQueue<Node>(); pq.add(new Node(source, 0)); while (!pq.isEmpty()) { int u = pq.poll().node; visited[u] = true; for (int v = 0; v < V; v++) { if (graph[u][v] != 0 && !visited[v] && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v]; pq.add(new Node(v, dist[v])); } } } } // 打印最短路径 public void printShortestPaths() { System.out.println("从顶点" + source + "到其他顶点的最短路径:"); for (int i = 0; i < V; i++) { if (i == source) continue; System.out.println("顶点" + source + "到顶点" + i + "的最短路径距离为:" + dist[i]); } } // 辅助类,用于存储顶点及其距离 class Node implements Comparable<Node> { int node; int dist; public Node(int node, int dist) { this.node = node; this.dist = dist; } @Override public int compareTo(Node o) { return this.dist - o.dist; } } public static void main(String[] args) { int[][] graph = { {0, 4, 0, 0, 0, 0, 0, 8, 0}, {4, 0, 8, 0, 0, 0, 0, 11, 0}, {0, 8, 0, 7, 0, 4, 0, 0, 2}, {0, 0, 7, 0, 9, 14, 0, 0, 0}, {0, 0, 0, 9, 0, 10, 0, 0, 0}, {0, 0, 4, 14, 10, 0, 2, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 1, 6}, {8, 11, 0, 0, 0, 0, 1, 0, 7}, {0, 0, 2, 0, 0, 0, 6, 7, 0} }; Dijkstra dijkstra = new Dijkstra(graph, 0); dijkstra.dijkstra(); dijkstra.printShortestPaths(); } } ``` 这段代码实现Dijkstra算法来计算图中某个顶点到其他顶点的最短路径。其中,dist数组用于存储最短路径的距离,visited数组用于记录顶点是否已被访问,graph是图的邻接矩阵表示。dijkstra()方法用于执行Dijkstra算法,printShortestPaths()方法用于打印最短路径。可以根据需要修改graph数组中的值来适应不同的测试案例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值