蓝桥杯省赛最短路径-模板

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

		// Floyd求最短路径
//		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];
//					}
//				}
//			}
//		}
//		
//		System.out.println(map[1][2021]);
//		
//		
//		for (int i = 0; i < 3; i++) {
//			for (int j = 0; j < n; j++) {
//				System.out.print(map[i][j]+"    ");
//			}
//			System.out.println();
//		}

		// 实现记录路径
		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);
				}
			}
		}
		
		//Djikstra求最短路径
		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));
//					list.add(new edge(j,i,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);
	}

}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值