算法思想:贪心算法
实际问题:单源最短路径
编程语言:Java
单源最短路径算法,又称迪杰斯特拉算法。其目的是寻找从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。
相关解释
算法步骤
注:贪心算法的思想主要就体现在第二步和第三步之中。
本代码求解的是无向有权图的最短路径,如果想求有向有权图的最短路径,则只需要将无向图的邻接矩阵改为有向图的邻接矩阵即可。
import java.util.Scanner;public class SSSP
{public static void main(String[] args){Scanner input = new Scanner(System.in);System.out.print("请输入图的顶点和边的个数(格式:顶点个数 边个数):");int n = input.nextInt(); //顶点的个数int m = input.nextInt(); //边的个数System.out.println();int[][] a = new int[n + 1][n + 1];//初始化邻接矩阵for(int i = 0; i < a.length; i++){for(int j = 0; j < a.length; j++){a[i][j] = -1; //初始化没有边}}System.out.println("请输入图的路径长度(格式:起点 终点 长度):");//总共m条边for(int i = 0; i < m; i++){//起点,范围1到nint s = input.nextInt();//终点,范围1到nint e = input.nextInt();//长度int l = input.nextInt();if(s >= 1 && s <= n && e >= 1 && e <= n){//无向有权图a[s][e] = l;a[e][s] = l;}}System.out.println();//距离数组int[] dist = new int[n+1];//前驱节点数组int[] prev = new int[n+1];int v =1 ;//顶点,从1开始dijkstra(v, a, dist, prev);}/*** 单源最短路径算法(迪杰斯特拉算法)* @param v 顶点* @param a 邻接矩阵表示图* @param dist 从顶点v到每个点的距离* @param prev 前驱节点数组*/public static void dijkstra(int v, int[][] a, int[] dist, int[] prev){int n = dist.length;/*** 顶点从1开始,到n结束,一共n个结点*/if(v > 0 && v <= n){//顶点是否放入的标志boolean[] s = new boolean[n];//初始化for(int i = 1; i < n; i++){//初始化为 v 到 i 的距离dist[i] = a[v][i];//初始化顶点未放入s[i] = false;//v到i无路,i的前驱节点置空if(dist[i] == -1){prev[i] = 0;}else{prev[i] = v;}}//v到v的距离是0dist[v] = 0;//顶点放入s[v] = true;//共扫描n-2次,v到v自己不用扫for(int i = 1; i < n - 1; i++){int temp = Integer.MAX_VALUE;//u为下一个被放入的节点int u = v;//这个for循环为第二步,观测域为v的观测域//遍历所有顶点找到下一个距离最短的点for(int j = 1; j < n; j++){//j未放入,且v到j有路,且v到当前节点路径更小if(!s[j] && dist[j] != -1 && dist[j] < temp){u = j;//temp始终为最小的路径长度temp = dist[j];}}//将得到的下一节点放入s[u] = true;//这个for循环为第三步,用u更新观测域for(int k = 1; k < n; k++){if(!s[k] && a[u][k] != -1){int newdist=dist[u] + a[u][k];if(newdist < dist[k] || dist[k] == -1){dist[k] = newdist;prev[k] = u;}}}}}for(int i = 2; i < n; i++){System.out.println(i + "节点的最短距离是:"+ dist[i] + ";前驱点是:" + prev[i]);}}
}