当前位置: 首页 > article >正文

【代码随想录Day57】图论Part08

拓扑排序精讲

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

import java.util.*;

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

        // 读取文件数量 n 和依赖关系数量 m
        int n = scanner.nextInt();
        int m = scanner.nextInt();

        // 初始化记录文件依赖关系的列表和每个文件的入度数组
        List<List<Integer>> umap = new ArrayList<>(n); // 记录文件依赖关系
        int[] inDegree = new int[n]; // 记录每个文件的入度

        // 初始化 umap,每个文件的依赖列表
        for (int i = 0; i < n; i++) {
            umap.add(new ArrayList<>());
        }

        // 读取依赖关系
        for (int i = 0; i < m; i++) {
            int s = scanner.nextInt(); // 依赖的源文件
            int t = scanner.nextInt(); // 依赖的目标文件
            umap.get(s).add(t); // 记录s指向哪些文件
            inDegree[t]++; // t的入度加一,表示有一个文件依赖于t
        }

        // 使用 ArrayDeque 作为队列来进行拓扑排序
        Deque<Integer> queue = new ArrayDeque<>();

        // 将所有入度为0的文件加入队列
        for (int i = 0; i < n; i++) {
            if (inDegree[i] == 0) {
                queue.add(i); // 入度为0的文件可以作为开头
            }
        }

        // 存储拓扑排序结果
        List<Integer> result = new ArrayList<>();

        // 拓扑排序过程
        while (!queue.isEmpty()) {
            int cur = queue.poll(); // 当前选中的文件
            result.add(cur); // 将当前文件加入结果列表

            // 遍历当前文件指向的所有文件
            for (int file : umap.get(cur)) {
                inDegree[file]--; // 当前文件指向的文件入度-1
                if (inDegree[file] == 0) {
                    queue.add(file); // 如果入度为0,则加入队列
                }
            }
        }

        // 检查是否完成了拓扑排序
        if (result.size() == n) {
            // 如果结果列表的大小等于文件数量,说明拓扑排序成功
            StringBuilder output = new StringBuilder();
            for (int i = 0; i < result.size(); i++) {
                output.append(result.get(i)); // 添加文件到输出
                if (i < result.size() - 1) {
                    output.append(" "); // 添加空格分隔文件
                }
            }
            System.out.println(output); // 输出最终结果
        } else {
            // 如果结果列表的大小不等于文件数量,说明存在循环依赖
            System.out.println(-1);
        }
    }
}

dijkstra(朴素版)精讲

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

import java.util.Arrays;
import java.util.Scanner;

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

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

        // 初始化图的邻接矩阵,使用 Integer.MAX_VALUE 表示无穷大
        int[][] grid = new int[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            Arrays.fill(grid[i], Integer.MAX_VALUE);
        }

        // 读取边的信息,建立邻接矩阵
        for (int i = 0; i < m; i++) {
            int p1 = scanner.nextInt();
            int p2 = scanner.nextInt();
            int val = scanner.nextInt();
            // 存储边的权值,假设图是有向图
            grid[p1][p2] = Math.min(grid[p1][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];

        // Dijkstra 算法主循环
        for (int i = 1; i <= n; i++) {
            // 1. 找到未访问的节点中最小距离的节点
            int cur = -1;
            int minVal = Integer.MAX_VALUE;

            for (int v = 1; v <= n; ++v) {
                if (!visited[v] && minDist[v] < minVal) {
                    minVal = minDist[v];
                    cur = v; // 记录当前节点
                }
            }

            // 如果所有节点都已访问,或剩下的节点不可达,则退出循环
            if (cur == -1) break;

            visited[cur] = true; // 2. 标记当前节点已被访问

            // 3. 更新未访问节点到起始点的距离
            for (int v = 1; v <= n; v++) {
                // 如果有边且未访问,更新最短距离
                if (!visited[v] && grid[cur][v] != Integer.MAX_VALUE) {
                    minDist[v] = Math.min(minDist[v], minDist[cur] + grid[cur][v]);
                }
            }
        }

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

http://www.kler.cn/a/377859.html

相关文章:

  • 超萌!HTMLCSS:超萌卡通熊猫头
  • HarmonyOS使用arkTS拉起指定第三方应用程序
  • 【大数据学习 | HBASE】habse的表结构
  • #渗透测试#SRC漏洞挖掘# 操作系统-windows系统bat病毒
  • 修改HarmonyOS鸿蒙图标和名字,打包后安装到真机,应用图标丢失变成透明,修改名字也不生效,还是默认的labeL解决方案教程
  • js WebAPI黑马笔记(万字速通)
  • Rust语言有哪些数据类型?
  • linux super键是什么_linux终端的快捷命令汇总
  • Linux上本地部署KubeSphere与cpolar实现远程管理和监控集群
  • 在centos中安装cmake
  • JVM 类加载机制详解
  • redis详细教程(7.哨兵)
  • 为数据集而生的 SQL 控制台
  • 私有化视频平台EasyCVR视频汇聚平台接入RTMP协议推流为何无法播放?
  • 【LeetCode】每日一题 2024_11_2 使两个整数相等的位更改次数(位运算/模拟)
  • OPENAI官方prompt文档解析
  • 基于知识引导提示的因果概念提取(论文复现)
  • linux 系统扩容
  • (二 上)VB 2010 设计初步
  • Apache Hive 通过Docker快速入门
  • 华为OD机试真题-组装最大可靠性设备-2024年OD统一考试(E卷)
  • Linux下安装Redis基本步骤
  • 总结一些高级的SQL技巧
  • 收音机天线的耦合方式
  • 6.1、实验一:静态路由
  • java毕业设计之基于Bootstrap的常州地方旅游管理系统的设计与实现(springboot)