迪杰斯特拉,最短路径

本文介绍了Dijkstra算法,一种用于找到加权无环图中从特定起点到所有其他顶点最短路径的贪心算法。算法核心是通过优先队列逐步更新节点的最短距离。文中提供了一个Java实现的例子,该例子适用于没有负权值的图,并给出了POJ_2387的例题。代码中展示了如何维护优先队列并更新节点距离,直至找到所有顶点的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1 问题描述
何为Dijkstra算法?
Dijkstra算法功能:给出加权连通图中一个顶点,称之为起点,找出起点到其它所有顶点之间的最短距离。
Dijkstra算法思想:采用贪心法思想,进行n-1次查找(PS:n为加权连通图的顶点总个数,除去起点,则剩下n-1个顶点),第一次进行查找,找出距离起点最近的一个顶点,标记为已遍历;下一次进行查找时,从未被遍历中的顶点寻找距离起点最近的一个顶点, 标记为已遍历;直到n-1次查找完毕,结束查找,返回最终结果。


2 解决方案
在这里插入图片描述
在这里插入图片描述

3 题意
例题: POJ_2387

迪杰斯特拉算法的特点 :
1.没有 负权值的图
2.给定了起点和终点的图

不进行点的标记,只进行权值的比较
示例代码:

package tuLun;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class A_迪杰斯特拉_test {
	static int N,M;
	static ArrayList<ArrayList<int[]>> nodeArryList;
	static PriorityQueue<nodePoint> pQueue;
	static int[] pointDis;  //记录到达当前节点的最大值
	static class nodePoint implements Comparable<nodePoint>{
		int getPoint;
		int vule;
		public nodePoint(int getPoint, int vule) {
			this.getPoint = getPoint;
			this.vule = vule;
		}
		//重写 compareTo 方法
		@Override
		public int compareTo(nodePoint o) {
			return this.vule == o.vule? this.getPoint-o.getPoint : this.vule -o.vule;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());  //边
		M = Integer.parseInt(st.nextToken());  //点
		
		nodeArryList = new ArrayList<ArrayList<int[]>>();
		for (int i = 0; i <= M; i++) {
			nodeArryList.add(new ArrayList<int[]>());
		}
		pointDis = new int[M+1];
		Arrays.fill(pointDis, Integer.MAX_VALUE);
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			int s = Integer.parseInt(st.nextToken());
			int e = Integer.parseInt(st.nextToken());
			int v = Integer.parseInt(st.nextToken());
			nodeArryList.get(s).add(new int[] {e,v});
			nodeArryList.get(e).add(new int[] {s,v});
		}
		getMinPath(1);
		System.out.println(pointDis[M]);
	}
	private static void getMinPath(int i) {
		pointDis[i] = 0;  //第一节点的  dis  最小值 设置维0
		pQueue = new PriorityQueue<nodePoint>();
		pQueue.add(new nodePoint(i, 0));  //加入第一个节点, 高达的点为1,到达1节点,需要的权值设定为 0
		while(!pQueue.isEmpty()) {
			nodePoint tempNode = pQueue.poll();
			int getPoint = tempNode.getPoint;
			for (int j = 0; j < nodeArryList.get(getPoint).size(); j++) {
				int getPointTemp = nodeArryList.get(getPoint).get(j)[0];
				int getPointDis = pointDis[getPointTemp];
				int getValTemp = nodeArryList.get(getPoint).get(j)[1];
				//节点没有被访问过 ,并且当前节点的值(dis) + 下一个节点的权值  < 下一个点中记录的节点最小值(dis)   ,因为时求最短路经
				if (getPointDis > getValTemp+pointDis[getPoint]) {
					pointDis[getPointTemp] = getValTemp+pointDis[getPoint];
					pQueue.add(new nodePoint(getPointTemp, getValTemp));
				}
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值