- 有向图和无向图的最短路没有区别(无向图就是特殊的有向图)
- 图的存储——稠密图(稀疏矩阵)&&稀疏图(邻接表)
一、单源最短路
1、边权均为正数——Dijkstra算法
- 存在重边和自环问题
- 自环肯定不会出现在最短路中
- 重边只保留最短边
import java.util.Scanner;
public class Main {
static final int INF = 0x3f;
static int n,m;
static int [][]g = new int[n+5][n+5]; // 邻接矩阵存储图
static int []dist = new int[n+5]; // 存储从源点到各点的最短距离
static boolean []st = new boolean[n+5];// 是否已经是最短距离
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
// 初始化距离
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if( i == j ) g[i][j] = 0;
else g[i][j] = INF;
}
}
// 建图
while (m--!=0){
int x = in.nextInt();
int y = in.nextInt();
int d = in.nextInt();
g[x][y] = Math.min(g[x][y],d);
}
int t = Dijkstra();
System.out.println(t);
}
static int Dijkstra(){
// 初始化距离
for (int i = 1; i <= n; i++)
dist[i] = INF;
dist[1] = 0;
for (int i = 0; i < n; i++){
int t = -1;
for (int j = 1; j <= n; j++)
// 在st未false的点中找最小的dist
if(!st[j]&&(t == -1 || dist[t] > dist[j]))
t = j;
st[t] = true;
for (int j = 1; j <= n; j++){
dist[j] = Math.min(dist[j], dist[t] + g[t][j]);
}
}
if(dist[n]==0x3f3f3f){
return -1;
}
return dist[n];
}
}
- 利用堆优化
待更新~~~
2、边权存在负数
2.1 Bellman-Ford算法
2.2 SPFA算法
待更新~~~SPFA算法
二、多源汇最短路——Floyd算法
- 邻接矩阵存储图
import java.util.Collections;
import java.util.Scanner;
public class Main {
static final int INF = 0x3f;
static int n,m;
static int [][]g = new int[n+5][n+5]; // 邻接矩阵存储图
static int []dist = new int[n+5]; // 存储从源点到各点的最短距离
static boolean []st = new boolean[n+5];// 是否已经是最短距离
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
// 初始化距离
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if( i == j ) g[i][j] = 0;
else g[i][j] = INF;
}
}
// 建图
while (m--!=0){
int x = in.nextInt();
int y = in.nextInt();
int d = in.nextInt();
g[x][y] = Math.min(g[x][y],d);
}
// Floyd算法
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
g[i][j] = Math.min(g[i][j],g[i][k]+g[k][j]);
}
}
}
}
}