【代码随想录Day58】图论Part09

dijkstra(堆优化版)精讲

题目链接/文章讲解:代码随想录

java 复制代码
import java.util.*;

class Edge {
    int to;  // 邻接顶点
    int val; // 边的权重

    Edge(int to, int val) {
        this.to = to;
        this.val = val;
    }
}

class Pair<U, V> {
    public final U first;  // 节点
    public final V second; // 从源点到该节点的权重

    public Pair(U first, V second) {
        this.first = first;
        this.second = second;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 读取节点数和边数
        int n = scanner.nextInt();
        int m = scanner.nextInt();

        // 创建图的邻接表
        List<List<Edge>> graph = new ArrayList<>(n + 1);
        for (int i = 0; i <= n; i++) {
            graph.add(new ArrayList<>());
        }

        // 读取边的信息
        for (int i = 0; i < m; i++) {
            int p1 = scanner.nextInt();
            int p2 = scanner.nextInt();
            int val = scanner.nextInt();
            graph.get(p1).add(new Edge(p2, val));
        }

        int start = 1;  // 起点
        int end = n;    // 终点

        // 存储从源点到每个节点的最短距离
        int[] minDist = new int[n + 1];
        Arrays.fill(minDist, Integer.MAX_VALUE);
        minDist[start] = 0;  // 起始点到自身的距离为0

        // 记录顶点是否被访问过
        boolean[] visited = new boolean[n + 1];

        // 优先队列,用于选择当前最短路径的节点
        PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>(Comparator.comparingInt(pair -> pair.second));

        // 初始化队列,添加源点
        pq.add(new Pair<>(start, 0));

        while (!pq.isEmpty()) {
            // 取出当前距离源点最近的节点
            Pair<Integer, Integer> cur = pq.poll();
            int currentNode = cur.first;

            // 如果该节点已被访问,跳过
            if (visited[currentNode]) continue;

            // 标记该节点为已访问
            visited[currentNode] = true;

            // 更新与当前节点相连的邻接节点的路径
            for (Edge edge : graph.get(currentNode)) {
                // 如果该邻接节点未被访问且新路径更短,则更新最短路径
                if (!visited[edge.to] && minDist[currentNode] + edge.val < minDist[edge.to]) {
                    minDist[edge.to] = minDist[currentNode] + edge.val;
                    pq.add(new Pair<>(edge.to, minDist[edge.to])); // 将新路径加入优先队列
                }
            }
        }

        // 输出结果
        System.out.println(minDist[end] == Integer.MAX_VALUE ? -1 : minDist[end]);
    }
}

Bellman_ford 算法精讲

题目链接/文章讲解:代码随想录

java 复制代码
import java.util.*;

public class Main {

    // 定义边的内部类
    static class Edge {
        int from; // 起始节点
        int to;   // 结束节点
        int val;  // 边的权重

        public Edge(int from, int to, int val) {
            this.from = from;
            this.to = to;
            this.val = val;
        }
    }

    public static void main(String[] args) {
        // 输入处理
        Scanner scanner = new Scanner(System.in);
        int numberOfNodes = scanner.nextInt(); // 节点数量
        int numberOfEdges = scanner.nextInt();  // 边的数量
        List<Edge> edges = new ArrayList<>();

        // 读取每一条边的信息
        for (int i = 0; i < numberOfEdges; i++) {
            int from = scanner.nextInt();
            int to = scanner.nextInt();
            int val = scanner.nextInt();
            edges.add(new Edge(from, to, val));
        }

        // 存储从起点到各节点的最小距离
        int[] minDistance = new int[numberOfNodes + 1];
        Arrays.fill(minDistance, Integer.MAX_VALUE); // 初始化最小距离为无穷大
        minDistance[1] = 0; // 起点到自身的距离为0

        // 执行 Bellman-Ford 算法,放松所有边 n-1 次
        for (int i = 1; i < numberOfNodes; i++) {
            for (Edge edge : edges) {
                // 如果起始节点的距离不为无穷大,且通过当前边可以找到更短的路径
                if (minDistance[edge.from] != Integer.MAX_VALUE) {
                    int newDistance = minDistance[edge.from] + edge.val;
                    if (newDistance < minDistance[edge.to]) {
                        minDistance[edge.to] = newDistance; // 更新最小距离
                    }
                }
            }
        }

        // 输出结果
        if (minDistance[numberOfNodes] == Integer.MAX_VALUE) {
            System.out.println("unconnected"); // 如果目标节点不可达
        } else {
            System.out.println(minDistance[numberOfNodes]); // 输出目标节点的最小距离
        }

        scanner.close(); // 关闭扫描器以释放资源
    }
}
相关推荐
为美好的生活献上中指2 分钟前
java每日精进 5.14【参数校验】
java·开发语言·spring boot·tomcat
qq_12498707538 分钟前
原生小程序+springboot+vue+协同过滤算法的音乐推荐系统(源码+论文+讲解+安装+部署+调试)
java·spring boot·后端·小程序·毕业设计·课程设计·协同过滤
曾昭武19 分钟前
IDEA怎么汉化&idea中文改回英文版
java·intellij-idea·idea汉化·idea怎么汉化·idea转回英文
末央&20 分钟前
【数据结构】手撕AVL树(万字详解)
数据结构·c++
序属秋秋秋21 分钟前
《数据结构初阶》【二叉树 精选9道OJ练习】
c语言·数据结构·c++·算法·leetcode
后青春期的诗go23 分钟前
基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(一)
开发语言·后端·rust
Tiny番茄23 分钟前
LeetCode 235. 二叉搜索树的最近公共祖先 LeetCode 701.二叉搜索树中的插入操作 LeetCode 450.删除二叉搜索树中的节点
数据结构·算法·leetcode
信徒_1 小时前
SpringBoot 自动装配流程
java·spring boot·后端
景天科技苑1 小时前
【Rust闭包】rust语言闭包函数原理用法汇总与应用实战
开发语言·后端·rust·闭包·闭包函数·rust闭包·rust闭包用法
小薛博客2 小时前
4、前后端联调文生文、文生图事件
java·ai