最短路径Dijkstra新版
import java.util.*;
public class Main {
static Scanner sc = new Scanner(System.in);
static final int INF = Integer.MAX_VALUE;
// 边类:存储邻接表中的边信息
static class Edge {
public Edge(Integer t, Integer w) {
this.t = t; // 目标节点
this.w = w; // 边权重
}
Integer t; // 目标节点编号
Integer w; // 边的权重
}
public static void main(String[] args) {
// 输入:n个节点,m条边
int n, m;
n = sc.nextInt();
m = sc.nextInt();
// 邻接表:graph[i]表示从节点i出发的所有边
List<List<Edge>> graph = new ArrayList<>();
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<>());
}
// 建图过程
int s, t, w;
for (int i = 0; i < m; i++) {
s = sc.nextInt(); // 起点
t = sc.nextInt(); // 终点
w = sc.nextInt(); // 权重
boolean found = false;
// 检查是否已存在s->t的边(处理重边)
for (Edge edge : graph.get(s)) {
if (edge.t.equals(t)) { // 找到相同边
if (edge.w > w) { // 保留最小权重
edge.w = w;
}
found = true;
break;
}
}
// 如果没有找到相同边,添加新边
if (!found) {
graph.get(s).add(new Edge(t, w));
}
}
// Dijkstra算法核心数据结构
int[] mindist = new int[n + 1]; // 最短距离数组:mindist[i] = 从起点1到i的最短距离
boolean[] visited = new boolean[n + 1]; // 访问标记数组:visited[i] = 节点i是否已确定最短路径
int start = 1, end = n; // 起点为1,终点为n
// 初始化:起点距离为0,其他为无穷大
Arrays.fill(mindist, INF);
mindist[start] = 0;
// Dijkstra主循环:执行n次(最多n个节点)
for (int i = 1; i <= n; i++) {
int cur = -1; // 当前选择的节点
int minVal = INF; // 当前最小距离
// 在未访问节点中找距离最小的节点
for (int j = 1; j <= n; j++) {
if (!visited[j] && mindist[j] < minVal) {
minVal = mindist[j];
cur = j;
}
}
// 如果没有可选节点,提前退出
if (cur == -1) break;
visited[cur] = true; // 标记当前节点已确定最短路径
// 松弛操作:更新当前节点的所有邻接点距离
for (Edge edge : graph.get(cur)) {
// 如果通过cur到edge.t的距离更短,则更新
if (mindist[cur] + edge.w < mindist[edge.t]) {
mindist[edge.t] = mindist[cur] + edge.w;
}
}
}
// 输出结果
if (mindist[end] == INF) { // 无法到达终点
System.out.println(-1);
} else { // 可达,输出最短距离
System.out.println(mindist[end]);
}
sc.close();
}
}
public class Main {
static Scanner sc = new Scanner(System.in);
static final int INF = Integer.MAX_VALUE;
// 边类:存储邻接表中的边信息
static class Edge {
public Edge(Integer t, Integer w) {
this.t = t; // 目标节点
this.w = w; // 边权重
}
Integer t; // 目标节点编号
Integer w; // 边的权重
}
public static void main(String[] args) {
// 输入:n个节点,m条边
int n, m;
n = sc.nextInt();
m = sc.nextInt();
// 邻接表:graph[i]表示从节点i出发的所有边
List<List<Edge>> graph = new ArrayList<>();
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<>());
}
// 建图过程
int s, t, w;
for (int i = 0; i < m; i++) {
s = sc.nextInt(); // 起点
t = sc.nextInt(); // 终点
w = sc.nextInt(); // 权重
boolean found = false;
// 检查是否已存在s->t的边(处理重边)
for (Edge edge : graph.get(s)) {
if (edge.t.equals(t)) { // 找到相同边
if (edge.w > w) { // 保留最小权重
edge.w = w;
}
found = true;
break;
}
}
// 如果没有找到相同边,添加新边
if (!found) {
graph.get(s).add(new Edge(t, w));
}
}
// Dijkstra算法核心数据结构
int[] mindist = new int[n + 1]; // 最短距离数组:mindist[i] = 从起点1到i的最短距离
boolean[] visited = new boolean[n + 1]; // 访问标记数组:visited[i] = 节点i是否已确定最短路径
int start = 1, end = n; // 起点为1,终点为n
// 初始化:起点距离为0,其他为无穷大
Arrays.fill(mindist, INF);
mindist[start] = 0;
// Dijkstra主循环:执行n次(最多n个节点)
for (int i = 1; i <= n; i++) {
int cur = -1; // 当前选择的节点
int minVal = INF; // 当前最小距离
// 在未访问节点中找距离最小的节点
for (int j = 1; j <= n; j++) {
if (!visited[j] && mindist[j] < minVal) {
minVal = mindist[j];
cur = j;
}
}
// 如果没有可选节点,提前退出
if (cur == -1) break;
visited[cur] = true; // 标记当前节点已确定最短路径
// 松弛操作:更新当前节点的所有邻接点距离
for (Edge edge : graph.get(cur)) {
// 如果通过cur到edge.t的距离更短,则更新
if (mindist[cur] + edge.w < mindist[edge.t]) {
mindist[edge.t] = mindist[cur] + edge.w;
}
}
}
// 输出结果
if (mindist[end] == INF) { // 无法到达终点
System.out.println(-1);
} else { // 可达,输出最短距离
System.out.println(mindist[end]);
}
sc.close();
}
}
全部评论
相关推荐
02-18 23:43
中国科学院大学 Java 点赞 评论 收藏
分享
AliLexiWal...:游戏链接合集:
http://www.silencer76.com/nowcoderPuzzle/
https://www.alilexiwalker.top/nowcoderPuzzle/
https://codebennylaw.github.io/nowcoderPuzzle/



点赞 评论 收藏
分享
肖先生~:如果确实觉得需要提升自己,可以去考研
点赞 评论 收藏
分享