# 最短路径算法比较（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 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();
}
for(int i=0;i<=T;i++){
dist[i] =INF;
}
int x,y,z;
for(int i=1;i<=R;i++){
x = in.nextInt();y=in.nextInt();z=in.nextInt();
}
for(int i=1;i<=P;i++){
x = in.nextInt();y=in.nextInt();z=in.nextInt();
}
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();
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;
}
}
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.Queue;
import java.util.Scanner;

public class SPFA_ {
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();
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++){
dist[i] =INF;
}
int x,y,z;
for(int i=1;i<=R;i++){
x = in.nextInt();
y = in.nextInt();
z = in.nextInt();

}
for(int i=1;i<=P;i++){
x = in.nextInt();
y = in.nextInt();
z = in.nextInt();
}
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;
q.offer(S);
visited[S] = true;
while(!q.isEmpty()){
int u = q.poll();
int v;
visited[u] = false;
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;

}
}
class Edge_{
int to;
int next;
int dis;
}
``````

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