最短路径算法比较(Dijkstra、Bellman-Ford、SPFA)及实现(Java)

《最短路径算法比较(Dijkstra、Bellman-Ford、SPFA)及实现(Java)》

Bellman-Ford(Java)

package com;

import java.util.Scanner;

public class Bellman_Ford {
	private static E edge[];
	private static int nodenum,edgenum,source;//节点数、边数、原点
	private static int dist[];//节点到源点最小距离
	public static void init(){
		Scanner in = new Scanner(System.in);
		nodenum= in.nextInt();
		edgenum = in.nextInt();
		source = in.nextInt();
		dist = new int[nodenum+1];
		edge = new E[edgenum+1];
		for(int i=0;i<edge.length;i++){
			edge[i] =new E();
		}
		dist[source] = 0;
		
		for(int i=1;i<=edgenum;i++){
			edge[i].start=in.nextInt();
			edge[i].end = in.nextInt();
			edge[i].weight = in.nextInt();
			if(edge[i].start==source){
				dist[edge[i].end] = edge[i].weight;
			}
		}
	}
	//松弛
	public static void relax(int start,int end,int weight){
		if(dist[end]>dist[start]+weight){
			dist[end] = dist[start]+weight;
		}
	}
	public static boolean bellmanFord(){
		for(int i=1;i<=nodenum-1;i++){
			for(int j=1;j<=edgenum;j++){
				relax(edge[j].start,edge[j].end,edge[j].weight);
			}
		}
		boolean flag =true;
		//判断是否有负权环路
		for(int i=1;i<=edgenum;i++){
			if(dist[edge[i].end]>dist[edge[i].start]+edge[i].weight){
				flag = false;
				break;
			}
		}
		return flag;
	}
	public static void main(String[] args) {
		init();
		if(bellmanFord()){
			for(int i=1;i<=nodenum;i++){
				System.out.print(dist[i]+" ");
			}
			
		}
	}

}
//边
class E{
	int start;
	int end;
	int weight;
}

Dijkstra(O(V^2))

package com;

import java.util.Scanner;

public class DijkstraSP {
	public static int maxnum = 100;
	public static int maxint = 99999;
	static int dist[] = new int[maxnum];
	static int prev[] = new int[maxnum];
	static int c[][] = new int[maxnum][maxnum];
	static int n;
	static int line;

	public static void Dijkstra(int n, int v, int[] dist, int prev[], int c[][]) {
		boolean S[] = new boolean[maxnum];
		for (int i = 1; i <= n; i++) {
			dist[i] = c[v][i];
			S[i] = false;
			if (dist[i] == maxint) {
				prev[i] = 0;
			} else {
				prev[i] = v;
			}
		}
		dist[v] = 0;
		S[v] = true;
		for (int j = 2; j <= n; j++) {
			int tmp = maxint;
			int u = v;
			for (int m = 1; m <= n; ++m) {
				if ((!S[m]) && dist[m] < tmp) {
					u = m;
					tmp = dist[m];
				}
			}
			S[u] = true;
			for (int p = 1; p <= n; p++) {
				if ((!S[p]) && c[u][p] < maxint) {
					int newdist = dist[u] + c[u][p];
					if (newdist < dist[p]) {
						dist[p] = newdist;
						prev[p] = u;
					}
				}
			}
		}

	}

	static void serch(int prev[], int v, int u) {
		int que[] = new int[maxnum];
		int tot = 1;
		que[tot] = u;
		tot++;
		int tmp = prev[u];
		while (tmp != v) {
			que[tot] = tmp;
			tot++;
			tmp = prev[tmp];
		}
		que[tot] = v;
		for (int i = tot; i >= 1; --i) {
			if (i != 1) {
				System.out.print(que[i] + "->");
			} else {
				System.out.println(que[i]);
			}
		}

	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		line = in.nextInt();
		int p, q, len;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; ++j) {
				c[i][j] = maxint;
			}
		}
		for (int i = 1; i <= line; i++) {
			p = in.nextInt();
			q = in.nextInt();
			len = in.nextInt();
			if (len < c[p][q]) {
				c[p][q] = len;
				c[q][p] = len;
			}
		}
		for (int i = 1; i <= n; ++i)
			dist[i] = maxint;
		for (int i = 1; i <= n; ++i) {
			for (int j = 1; j <= n; ++j)
				System.out.print(c[i][j] + " ");
			System.out.println();
		}
		Dijkstra(n, 1, dist, prev, c);
		System.out.println("源点到最后一个顶点的最短路径长度" + dist[n]);
		serch(prev, 1, n);
	}
}

Dijkstra(优先队列)

package Test;

import java.util.PriorityQueue;
import java.util.Scanner;

public class DijkstraHeap {
	private static final int INF = 9999;
	static int N;//顶点数
	static int V;//边数
	static int dist[];
	static Edge1 edge[];
	static int head[];
	static int m =1;
	public static void main(String[] args) {
		Scanner in =new Scanner(System.in);
		int T,R,P,S;
		T= in.nextInt();R = in.nextInt();P = in.nextInt();S= in.nextInt();
		N =T;
		V=2*R+P;
		dist = new int[N+10];
		edge  = new Edge1[V+10];
		for(int i=0;i<edge.length;i++){
			edge[i] = new Edge1();
		}
		head = new int[N+10];
		for(int i=0;i<=T;i++){
			head[i]=-1;
			dist[i] =INF;
		}
		int x,y,z;
		for(int i=1;i<=R;i++){
			x = in.nextInt();y=in.nextInt();z=in.nextInt();
			add_edge(x,y,z);
			add_edge(y,x,z);
		}
		for(int i=1;i<=P;i++){
			x = in.nextInt();y=in.nextInt();z=in.nextInt();
			add_edge(x,y,z);
		}
		dijkstra(S);
		for(int i=1;i<=T;i++){
			if(dist[i]==INF){
				System.out.println("NO PATH");
			}else{
				System.out.println(dist[i]);
			}
		}
	}
	static void dijkstra(int s){
		for(int i=1;i<=N;i++){
			dist[i] =INF;
		}
		dist[s] = 0;
		PriorityQueue<Node> q = new PriorityQueue<>();
		q.offer(new Node(s,0));
		while(!q.isEmpty()){
			int u,v,val;
			u = q.peek().id;
			val = q.peek().val;
			q.poll();
			for(int i=head[u];i!=-1;i=edge[i].next){
				v = edge[i].to;
				if(dist[v]>dist[u]+edge[i].val){
					dist[v] = dist[u] +edge[i].val;
					q.offer(new Node(v,dist[v]));
				}
			}
		}
		
	}
	static void add_edge(int u,int v,int val){
		edge[m].to = v;
		edge[m].val = val;
		edge[m].next = head[u];
		head[u] =m++;
	}
}
class Node implements Comparable<Node>{
	int id;
	int val;
	public Node(){
		
	}
	public Node(int id,int val){
		this.id = id;
		this.val = val;
	}
	@Override
	public int compareTo(Node o) {
		return val-o.val;
	}
}
class Edge1{
	int to;
	int next;
	int val;
}

Floyd:

package com;

import java.util.Scanner;

public class Floyd {
	private static final int INF = 9999;
	private static MGraph g;
	public static void main(String[] args) {
		input();
		floyd(g);
	}
	public static void floyd(MGraph g) {
		int A[][]= new int[g.n][g.n];
		int path[][] = new int[g.n][g.n];
		for(int i=0;i<g.n;i++){
			for(int j=0;j<g.n;j++){
				A[i][j]= g.edges[i][j];
				path[i][j] = -1;
			}
		}
		for(int k=0;k<g.n;k++){
			for(int i=0;i<g.n;i++){
				for(int j=0;j<g.n;j++){
					if(A[i][j]>A[i][k]+A[k][j]){
						A[i][j] = A[i][k]+A[k][j];
						path[i][j] =k;
					}
				}
			}
		}
		Dispath(A,path,g.n);
		
		
	}
	private static void Dispath(int[][] A, int[][] path, int n) {
		int i,j;
		for(i=0;i<n;i++){
			for(j=0;j<n;j++){
				if(A[i][j]==INF){
					if(i!=j){
						System.out.println(i+" to "+j+" no access ");
					}
					
				}else{
					System.out.print(i+" to "+j+" length:"+A[i][j]);
					System.out.print(" "+i+" to "+j+" | path: "+i+",");
					Ppath(path,i,j);
					System.out.println(j);
					
				}
			}
		}
	}
	private static void  Ppath(int[][] path, int from, int to) {
		int k ;
		k = path[from][to];
		if(k==-1){
			return ;
		}
		Ppath(path,from,k);
		System.out.print(k+",");
		Ppath(path,k,to);
	}
	public static void input() {
		Scanner in =new Scanner(System.in);
		System.out.println("请输入顶点数和边数");
		g= new MGraph(in.nextInt(),in.nextInt());
		System.out.println("请输入顶点元素");
		for(int i=0;i<g.n;i++){
			g.vertex[i]=in.next();
		}
		for(int i=0;i<g.n;i++){
			for(int j=0;j<g.n;j++){
				g.edges[i][j] = INF;
				if(i==j){
					g.edges[i][j] = 0;
				}
			}
		}
		System.out.println("请输入两点之间的权值");
		int from,to;
		for(int k=0;k<g.e;k++){
			from  = in.nextInt();
			to  = in.nextInt();
			g.edges[from][to] = in.nextInt();
		}
	
		
	}
	
}
class MGraph{
	int n,e;//n 顶点数,e 边数
	String vertex[];
	int edges[][];
	public MGraph(int n ,int e){
		this.n = n;
		this.e = e;
		vertex = new String[n];
		edges = new int[n][n];
	}
}

SPFA:

package com;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class SPFA_ {
	private static int head[],dist[];
	private static boolean visited[];
	private static Edge_ edge[];
	static int INF= 9999;
	static int m = 1;
	public static void main(String[] args) {
		int T,R,P,S;
		Scanner in = new Scanner(System.in);
		T = in.nextInt();R= in.nextInt();P=in.nextInt();S = in.nextInt();
		head = new int[T+10];
		dist= new int[T+10];
		edge = new Edge_[2*R+P+10];
		for(int i=0;i<edge.length;i++){
			edge[i] = new Edge_();
		}
		visited = new boolean[T+10];
		for(int i=0;i<=T;i++){
			head[i] = -1;
			dist[i] =INF;
		}
		int x,y,z;
		for(int i=1;i<=R;i++){
			x = in.nextInt();
			y = in.nextInt();
			z = in.nextInt();
			add_edge(x,y,z);
			add_edge(y,x,z);
			
		}
		for(int i=1;i<=P;i++){
			x = in.nextInt();
			y = in.nextInt();
			z = in.nextInt();
			add_edge(x,y,z);
		}
		SPFA(S);
		for(int i=1;i<=T;i++){
			if(dist[i]==INF){
				System.out.println("NO PATH");
			}else{
				System.out.println(dist[i]);
			}
		}
	}
	private static void SPFA(int S) {
		dist[S] = 0;
		Queue<Integer> q = new LinkedList<>();
		q.offer(S);
		visited[S] = true;
		while(!q.isEmpty()){
			int u = q.poll();
			int v;
			visited[u] = false;
			for(int i=head[u];i!=-1;i=edge[i].next){
				v = edge[i].to;
				if(dist[u]!=INF && dist[v]>dist[u]+edge[i].dis){
					dist[v] = dist[u]+edge[i].dis;
					if(!visited[v]){
						visited[v] = true;
						q.offer(v);
					}
				}
			}
		}
	}
	private static void add_edge(int u, int v, int dis) {
		edge[m].to = v;
		edge[m].dis = dis;
		edge[m].next = head[u];
		head[u]=m++;
		
	}
}
class Edge_{
	int to;
	int next;
	int dis;
}

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/WiseWolf_Life/article/details/44900383
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞