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) ;
}
}