有权图单源最短路径Dijkstra算法

使用Dirkstra算法完成有权单源最短路径的算法,回忆一下当初学数据结构最难的图的部分,注意里面距离和收录点之间的运算关系,以及Dijkstra算法的步骤。示例为总共五个城市,五条路,城市编号从0到4,起始点为0,终点为3,路径为:0 - 4 => 5;0 - 1 => 2; 0 - 2 =>2; 1 - 3 =>1 ; 2 - 3 =>2;总共五条路径。

import java.util.*;

public class Dijkstra {
	static int[] dist;			//记录最短路径
	static int[][] map;			//图的存储,邻接矩阵
	static boolean[] visited;	        //收录使用
	static int M,N;				//M个城市,N条路
	static int start,end;		        //城市起点和终点
	static final int maxINF = 1 << 30;
	static int[] path;			//记录经过的路径
	static void dijkstra(){
		dist[start] = 0;		//起点距离为0
		visited[start] = true;	        //收录起点
		Arrays.fill(path, -1);
		
		for( int i = 0 ; i < M ;i++)	//初始化起点
			if( map[start][i] != maxINF ){
				dist[i] = map[start][i];
				path[i] = start;
			}
		
		while(true){
			int findMin = maxINF;
			int u = 0;
			for( int i = 0 ; i < M ; i++)	//寻找当前未被收录且dist中最小的值
				if( !visited[i] && dist[i] < findMin){
					u = i;
					findMin = dist[i];
				}
			if( findMin == maxINF)	//均被访问过
				break;
			visited[u] = true;		//收录该顶点
			for( int i = 0 ; i < M ; i++){
				if( !visited[i] && dist[u] + map[u][i] < dist[i]){
					dist[i] = dist[u] + map[u][i];
					path[i] = u;
				}
			}
		}
	}
	
	static void printPath(){	//利用堆栈实现输出路径
		 Deque<Integer> stack = new ArrayDeque<Integer>();
		 int e = end;
		 while( path[e] != -1){
			 stack.push(e);
			 e = path[e];
		 }
		System.out.print(start+" ");
		while( !stack.isEmpty()){
			int n = stack.pop();
			System.out.print(n+" ");
		}
	}
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		M = input.nextInt();	//0 - M-1总共M个城市
		map = new int[M][M];
		dist = new int[M];
		visited = new boolean[M];
		path = new int[M];
		for( int i = 0 ; i < M ; i++)
			Arrays.fill(map[i], maxINF); //图的每一个节点初始化长度为无穷大
		Arrays.fill(dist, maxINF);	//dist定义为正无穷大
		Arrays.fill(visited, false);
		N = input.nextInt();		//N条路
		start = input.nextInt();	//出发城市
		end = input.nextInt();		//终点城市
		for( int i = 0 ; i < N ; i++){
			int x = input.nextInt();
			int y = input.nextInt();
			int d = input.nextInt();
			map[x][y] = d;
		}
		dijkstra();
		/*for( int i = 0 ; i < M ; i++){
			for( int j = 0 ; j < M ; j++)
				System.out.print(map[i][j]+" ");
			System.out.println();
		}
		for( int i = 0 ; i < M ; i++)
			System.out.print(dist[i]+" ");
		System.out.println();
		for( int i = 0 ; i < M ; i++)
			System.out.print(path[i]+" ");
		System.out.println();*/
		System.out.println(dist[end]);
		printPath();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值