Dijkstra(迪杰斯特拉)算法刷题模板(附详细注释)及经典例题 - java语言

本文深入解析Dijkstra算法原理,对比邻接矩阵与邻接表的时间复杂度,阐述算法适用场景与限制,并通过经典例题及PAT甲级考试真题,演示如何求解单源最短路径问题,涵盖带权值、最短路径数量及资源优化等复杂情况。

dijkstra的题目一般给出每条边的起点、终点、权值,需要转化成邻接矩阵或邻接表
邻接矩阵的时间复杂度为O(v^2),
邻接表的时间复杂度为O(v^2+E)
dijkstra算法用于求单源最短路径,即某个顶点到其他所有顶点的最短路径。
dijkstra算法不适用于存在负权值的边的情况。
与《算法笔记》中另用数组d[]表示起点到各点的最短路径不同,本模板直接在原来的邻接矩阵中修改G[s][i],执行完dijkstra算法后,G[s][i]即为起点到各点的最短路径

dijkstra算法经典例题:

输入顶点数n、边数e、起始顶点s,下面e行为每条边的起点、终点、权值
输出起点s到所有顶点的最短路径、起点s到所有顶点的距离

样例1:
输入:
5 7 0
0 1 10
0 3 30
0 4 100
1 2 50
2 4 10
3 2 20
3 4 60

输出:
从0出发到0的最短路径为:0
从0出发到1的最短路径为:0 1
从0出发到2的最短路径为:0 3 2
从0出发到3的最短路径为:0 3
从0出发到4的最短路径为:0 3 2 4
0 10 50 30 60

样例1的邻接矩阵:
static int[][] w = {
{0,10,M,30,100},
{M,0,50,M,M},
{M,M,0,M,10},
{M,M,20,0,60},
{M,M,M,M,0}
};

样例2:
输入:
//6个顶点,8条边,起点为0号顶点。以下8行为8条边
//边0->1的边,权为1,下同
6 8 0
0 1 1
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3

输出:
从0出发到0的最短路径为:0
从0出发到1的最短路径为:0 1
从0出发到2的最短路径为:0 1 3 2
从0出发到3的最短路径为:0 1 3
从0出发到4的最短路径为:0 4
从0出发到5的最短路径为:0 1 3 2 5
0 1 5 3 4 6

import java.util.*;
public class Dijkstra模板 {
   
   
	
	static int MAXV=999;					//最大顶点数,由具体题目决定
    static int M=999999;					//不能用Integer.MAX_VALUE,否则做加法后可能会溢出
	  
	static int n,m,s;  						//n为顶点数,m为边数,s为起始顶点编号
	static int[][] G=new int[MAXV][MAXV];  	//一个有向图的邻接矩阵,
//与《算法笔记》中另用数组d[]表示起点到各点的最短路径不同,
//本模板直接在原来的邻接矩阵中修改G[s][i],执行完dijkstra算法后,G[s][i]即为起点到各点的最短路径

	static int[] v=new int[MAXV];    		//标记数组,v[i]=1表示i点已访问,初值均为0
	
	static String[] path=new String[MAXV]; 	//存放从start到其他各点的最短路径的字符串表示  
	
	//除了距离之外的第二标尺
//	static int cost[][]=new int[MAXV][MAXV]; cost代表新增的边权
//	static int c[]=new int[MAXV];            c代表从起点到各点的花费
	
//	static int resource[]=new int[MAXV];     resource代表新增的点权
//	static int r[]=new int[MAXV];		     r代表从起点到各点获得的资源
	
//	static int num[]=new int[MAXV];          num代表到各点的最短路径条数。
	
    public static void main(String[] args) {
   
     
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		s=sc.nextInt();

		for(int i=0;i<n;i++) {
   
   
			Arrays.fill(G[i], M);
			G[i][i]=0;
			path[i]=s+""; 
		} 
             
//      Arrays.fill(c, M);
//      c[s]=0;
//      r[s]=resource[s];
//      num[s]=1;

		for(int i=0;i<m;i++) {
   
   
			int v1=sc.nextInt();
			int v2=sc.nextInt();
			int weight=sc.nextInt();
//			int co=sc.nextInt();
			G[v1][v2]=weight;
//			G[v2][v1]=weight;  若为无向图,则加上这一句
//			cost[v1][v2]=co;
//			cost[v2][v1]=co;
		}
        
		dijkstra(s);

        for(int i=0;i<n;i++) {
   
   
            System.out.println("从"+s+"出发到"+i+"的最短路径为:"+path[i]);    
        }
		
		for(int i=0;i<n;i++) {
   
   
			System.out.print(G[s][i]+" ");
		}
		
		sc.close();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值