1. Floyd
package 最短路径;
import java.util.Arrays;
public class 省赛F_最短路径_Floyd {
public static void main(String[] args) {
int n = 2022;
int INF = 0x3f3f3f3f;
int[][] map = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
map[i][j] = INF;
}
}
for (int i = 1; i < n; i++) {
for (int j = i + 1; j < n && j <= i + 21; j++) {
if (j > 0) {
map[i][j] = map[j][i] = i * j / f(j, i);
}
}
}
String[][] path = new String[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
path[i][j]="";
}
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < n; j++) {
for (int j2 = 1; j2 < n; j2++) {
if (map[j][i] + map[i][j2] < map[j][j2]) {
map[j][j2] = map[j][i] + map[i][j2];
path[j][j2]=path[j][i]+i+"->"+path[i][j2];
}
}
}
}
System.out.println(map[1][2021]);
System.out.println(path[1][2021]);
}
static int f(int a, int b) {
return b == 0 ? a : f(b, a % b);
}
}
2. Dijkstar
package 最短路径;
import java.util.Arrays;
public class 省赛F_最短路径_Dijkstra {
public static void main(String[] args) {
int n = 2022;
int INF = 0x3f3f3f3f;
int[][] map = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
map[i][j]=INF;
}
}
for (int i = 1; i < n; i++) {
for (int j = i + 1; j < n && j <= i + 21; j++) {
if (j > 0) {
map[i][j] = map[j][i] = i * j / f(j, i);
}
}
}
int[] minWay = new int[n];
int[] vertex = new int[n];
String[] path=new String[n];
for (int i = 0; i < n; i++) {
path[i]=1+"->"+i;
}
vertex[1]=1;
minWay[1]=0;
for (int i = 2; i < n; i++) {
int min=Integer.MAX_VALUE;
int index=-1;
for (int j = 1; j < n; j++) {
if(vertex[j]==0&&map[1][j]<min) {
min=map[1][j];
index=j;
}
}
vertex[index]=1;
minWay[index]=min;
for (int j = 0; j < n; j++) {
if(vertex[j]==0&&map[1][index]+map[index][j]<map[1][j]) {
map[1][j]=map[1][index]+map[index][j];
path[j]=path[index]+"->"+j;
}
}
}
System.out.println(Arrays.toString(minWay));
System.out.println(Arrays.toString(map[1]));
System.out.println(minWay[2021]);
System.out.println(path[2021]);
}
static int f(int a, int b) {
return b == 0 ? a : f(b, a % b);
}
}
3. Dijkstra-plus
package 最短路径;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import 最短路径.Bellman_Ford.edge;
public class 省赛F_最短路径_Dijkstra_Plus {
static class edge {
int to;
int val;
public edge(int to, int val) {
this.to = to;
this.val = val;
}
public edge() {}
}
static List<edge>[] list;
static int[] dis;
static int INF=0x3f3f3f3f;
static int n = 2022;
public static void main(String[] args) {
list=new List[n];
for (int i = 1; i < n; i++) {
for (int j = i + 1; j < n && j <= i + 21; j++) {
if (j > 0) {
int a=i*j/gcd(j,i);
if(list[i]==null) list[i]=new ArrayList<>();
if(list[j]==null) list[j]=new ArrayList<>();
list[i].add(new edge(j,a));
list[j].add(new edge(i,a));
}
}
}
dis=new int[n];
boolean[] vis=new boolean[n];
Arrays.fill(dis, INF);
PriorityQueue<edge> pq=new PriorityQueue<>(new Comparator<edge>() {
@Override
public int compare(edge o1, edge o2) {
return o1.val-o2.val;
}
});
pq.add(new edge(1,0));
dis[1]=0;
while (!pq.isEmpty()) {
int x=pq.poll().to;
if(vis[x]) continue;
vis[x]=true;
for (edge e : list[x]) {
if(dis[x]+e.val<dis[e.to]) {
dis[e.to]=dis[x]+e.val;
pq.offer(new edge(e.to,dis[e.to]));
}
}
}
System.out.println(dis[2021]);
System.out.println(Arrays.toString(dis));
}
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
4. Bellman_Ford
package 最短路径;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Bellman_Ford {
static class edge {
int form;
int to;
int val;
public edge(int form, int to, int val) {
this.form = form;
this.to = to;
this.val = val;
}
public edge() {}
}
static List<edge> list;
static int[] dis;
static int INF=0x3f3f3f3f;
static int n = 2022;
public static void main(String[] args) {
list=new ArrayList<>();
dis=new int[n];
for (int i = 1; i < n; i++) {
for (int j = i + 1; j < n && j <= i + 21; j++) {
if (j > 0) {
int a=i*j/gcd(j,i);
list.add(new edge(i,j,a));
}
}
}
ford();
System.out.println(dis[2021]);
}
static void ford() {
Arrays.fill(dis, INF);
dis[1]=0;
for (int i = 2; i < n; i++) {
boolean f=true;
for (edge e: list) {
if(dis[e.form]+e.val<dis[e.to]) {
dis[e.to]=dis[e.form]+e.val;
f=false;
}
if(dis[e.to]+e.val<dis[e.form]) {
dis[e.form]=dis[e.to]+e.val;
f=false;
}
}
if(f) break;
}
}
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
5. SPFA
package 最短路径;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Queue;
public class SPFA {
static class edge {
int to;
int val;
public edge(int to, int val) {
this.to = to;
this.val = val;
}
public edge() {
}
}
static List<edge>[] list;
static int[] dis;
static int INF = 0x3f3f3f3f;
static int n = 2022;
public static void main(String[] args) {
list = new List[n];
for (int i = 1; i < n; i++) {
for (int j = i + 1; j < n && j <= i + 21; j++) {
if (j > 0) {
int a = i * j / gcd(j, i);
if (list[i] == null)
list[i] = new ArrayList<>();
if (list[j] == null)
list[j] = new ArrayList<>();
list[i].add(new edge(j, a));
list[j].add(new edge(i, a));
}
}
}
ford();
System.out.println(dis[2021]);
}
static void ford() {
dis=new int[n];
Arrays.fill(dis, INF);
dis[1] = 0;
Queue<Integer> q=new ArrayDeque<Integer>();
q.add(1);
while(!q.isEmpty()) {
int a=q.poll();
for (edge e : list[a]) {
if(dis[a]+e.val<dis[e.to]) {
dis[e.to]=dis[a]+e.val;
q.add(e.to);
}
}
}
}
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}