代码随想录打卡|Day51 图论(dijkstra(堆优化版)精讲、Bellman_ford 算法精讲)

图论part09

dijkstra(堆优化版)精讲(不熟悉)

代码随想录链接
题目链接


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

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

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

class MyComparison implements Comparator<Pair<Integer, Integer>> {
    @Override
    public int compare(Pair<Integer, Integer> lhs, Pair<Integer, Integer> rhs) {
        return Integer.compare(lhs.second, rhs.second);
    }
}

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>> grid = new ArrayList<>(n + 1);
        for (int i = 0; i <= n; i++) {
            grid.add(new ArrayList<>());
        }

        for (int i = 0; i < m; i++) {
            int p1 = scanner.nextInt();
            int p2 = scanner.nextInt();
            int val = scanner.nextInt();
            grid.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);

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

        // 优先队列中存放 Pair<节点,源点到该节点的权值>
        PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>(new MyComparison());

        // 初始化队列,源点到源点的距离为0,所以初始为0
        pq.add(new Pair<>(start, 0));

        minDist[start] = 0;  // 起始点到自身的距离为0

        while (!pq.isEmpty()) {
            // 1. 第一步,选源点到哪个节点近且该节点未被访问过(通过优先级队列来实现)
            // <节点, 源点到该节点的距离>
            Pair<Integer, Integer> cur = pq.poll();

            if (visited[cur.first]) continue;

            // 2. 第二步,该最近节点被标记访问过
            visited[cur.first] = true;

            // 3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)
            for (Edge edge : grid.get(cur.first)) { // 遍历 cur指向的节点,cur指向的节点为 edge
                // cur指向的节点edge.to,这条边的权值为 edge.val
                if (!visited[edge.to] && minDist[cur.first] + edge.val < minDist[edge.to]) { // 更新minDist
                    minDist[edge.to] = minDist[cur.first] + edge.val;
                    pq.add(new Pair<>(edge.to, minDist[edge.to]));
                }
            }
        }

        if (minDist[end] == Integer.MAX_VALUE) {
            System.out.println(-1); // 不能到达终点
        } else {
            System.out.println(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 sc = new Scanner(System.in);

        // 1. 输入处理
        int n = sc.nextInt();  // 节点数(编号1~n)
        int m = sc.nextInt();  // 边数
        List<Edge> edges = new ArrayList<>();  // 存储所有边

        // 读取每条边的信息
        for (int i = 0; i < m; i++) {
            int from = sc.nextInt();
            int to = sc.nextInt();
            int val = sc.nextInt();
            edges.add(new Edge(from, to, val));  // 添加到边列表
        }

        // 2. 初始化距离数组
        int[] minDist = new int[n + 1];  // minDist[i]表示节点1到节点i的最短距离
        Arrays.fill(minDist, Integer.MAX_VALUE);  // 初始化为无穷大
        minDist[1] = 0;  // 起点到自身的距离为0

        // 3. Bellman-Ford 核心算法:松弛操作
        for (int i = 1; i < n; i++) {  // 最多进行n-1轮松弛
            boolean updated = false;  // 标记本轮是否更新
            for (Edge edge : edges) {
                // 如果起点可达,且通过当前边可以缩短距离
                if (minDist[edge.from] != Integer.MAX_VALUE && 
                    minDist[edge.from] + edge.val < minDist[edge.to]) {
                    minDist[edge.to] = minDist[edge.from] + edge.val;  // 更新最短距离
                    updated = true;  // 标记有更新
                }
            }
            if (!updated) break;  // 提前终止:如果本轮未更新,说明已收敛
        }

        // 4. 输出结果
        if (minDist[n] == Integer.MAX_VALUE) {
            System.out.println("unconnected");  // 终点不可达
        } else {
            System.out.println(minDist[n]);  // 输出最短距离
        }
    }
}
相关推荐
1104.北光c°2 小时前
滑动窗口HotKey探测机制:让你的缓存TTL更智能
java·开发语言·笔记·程序人生·算法·滑动窗口·hotkey
仰泳的熊猫6 小时前
题目2570:蓝桥杯2020年第十一届省赛真题-成绩分析
数据结构·c++·算法·蓝桥杯
无极低码10 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发10 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
superior tigre11 小时前
22 括号生成
算法·深度优先
努力也学不会java12 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
旖-旎12 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针
ECT-OS-JiuHuaShan12 小时前
朱梁万有递归元定理,重构《易经》
算法·重构
智者知已应修善业13 小时前
【51单片机独立按键控制数码管移动反向,2片74CH573/74CH273段和位,按键按下保持原状态】2023-3-25
经验分享·笔记·单片机·嵌入式硬件·算法·51单片机