算法打卡:第十一章 图论part10

embedded/2024/12/22 1:19:16/

今日收获:Bellman_ford 队列优化算法(又名SPFA),bellman_ford之判断负权回路和单源有限最短路

1. Bellman_ford 队列优化算法(又名SPFA)

题目链接:94. 城市间货物运输 I (kamacoder.com)

思路:上篇文章中Bellman_ford算法是在每一次循环中对所有边进行松弛操作。实际上只需要对上一次更新的节点相连边进行松弛操作,可以使用队列来优化。

方法:

java">import java.util.*;public class Main{public static void main(String[] args){Scanner sc=new Scanner(System.in);// 接收数据int n=sc.nextInt();int m=sc.nextInt();List<List<Edge>> grid=new ArrayList<>(n+1);for (int i=0;i<n+1;i++){grid.add(new ArrayList<>());}for (int i=0;i<m;i++){int s=sc.nextInt();int t=sc.nextInt();int v=sc.nextInt();grid.get(s).add(new Edge(s,t,v));}// 初始化minDistint[] minDist=new int[n+1];Arrays.fill(minDist,Integer.MAX_VALUE);minDist[1]=0;// 存储已更新节点相连的点Queue<Integer> queue=new LinkedList<>();queue.add(1);// 判断节点是否已经在队列中boolean[] inQueue=new boolean[n+1];while (!queue.isEmpty()){int cur=queue.poll();inQueue[cur]=false;for (Edge edge:grid.get(cur)){if (minDist[cur]+edge.val<minDist[edge.to]){minDist[edge.to]=minDist[cur]+edge.val;if (!inQueue[edge.to]){queue.offer(edge.to);inQueue[edge.to]=true;}}}}if (minDist[n]!=Integer.MAX_VALUE){System.out.println(minDist[n]);}else {System.out.println("unconnected");}}
}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;}
}

2. bellman_ford之判断负权回路

题目链接:95. 城市间货物运输 II (kamacoder.com)

思路:这道题中出现了负权回路。在没有负权回路的图中,松弛 n 次以上 ,结果不会有变化;但在有负权回路的情况下,如果松弛 n 次,结果就会有变化了,因为有负权回路可以无限最短路径(一直绕圈,就可以一直得到无限小的最短距离)。

(1)如果没有用队列优化,则松弛n次看终点的成本会不会变化

(2)如果用队列优化的版本,假设每个节点和所有的节点相连则有n-1条边,每个节点最多放入队列n-1次。如果有优先队列则存在节点被放入队列n次

方法:

java">import java.util.*;public class Main{public static void main(String[] args){Scanner sc=new Scanner(System.in);// 接收数据int n=sc.nextInt();int m=sc.nextInt();List<List<Edge>> grid=new ArrayList<>(n+1);for (int i=0;i<n+1;i++){grid.add(new ArrayList<>());}for (int i=0;i<m;i++){int s=sc.nextInt();int t=sc.nextInt();int v=sc.nextInt();grid.get(s).add(new Edge(s,t,v));}// 初始化minDistint[] minDist=new int[n+1];Arrays.fill(minDist,Integer.MAX_VALUE);minDist[1]=0;// 存储已更新节点相连的点Queue<Integer> queue=new LinkedList<>();queue.add(1);// 判断节点是否已经在队列中boolean[] inQueue=new boolean[n+1];// 记录节点加入队列的次数int[] count=new int[n+1];count[1]++;// 是否存在负权回路boolean flag=false;while (!queue.isEmpty()){int cur=queue.poll();inQueue[cur]=false;for (Edge edge:grid.get(cur)){if (minDist[cur]+edge.val<minDist[edge.to]){minDist[edge.to]=minDist[cur]+edge.val;if (!inQueue[edge.to]){queue.offer(edge.to);inQueue[edge.to]=true;count[edge.to]++;}if (count[edge.to]==n){flag=true;while (!queue.isEmpty()){  // 结束内外层循环queue.poll();}break;}}}}if (flag){System.out.println("circle");return;}if (minDist[n]!=Integer.MAX_VALUE){System.out.println(minDist[n]);}else {System.out.println("unconnected");}}
}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;}
}

3. bellman_ford之单源有限最短路

题目链接:96. 城市间货物运输 III (kamacoder.com)

思路:因为最多可以经过k个城市,所以对所有边进行k+1次松弛操作。每一次松弛操作都要基于上一次松弛操作的结果(这个目前不明白,先这样写吧,之后填坑。讲解在这里代码随想录

方法:

java">import java.util.*;public class Main{public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();int m=sc.nextInt();// 存储边List<Edge> edges=new ArrayList<>(m);for (int i=0;i<m;i++){int s=sc.nextInt();int t=sc.nextInt();int v=sc.nextInt();edges.add(new Edge(s,t,v));}int src=sc.nextInt();int dst=sc.nextInt();int k=sc.nextInt();// minDist数组和初始化int[] minDist=new int[n+1];Arrays.fill(minDist,Integer.MAX_VALUE);minDist[src]=0;int[] copy=new int[n+1];for (int i=0;i<k+1;i++){  // k+1次松弛边copy=Arrays.copyOf(minDist,n+1);for (Edge edge:edges){if (copy[edge.from]!=Integer.MAX_VALUE&&copy[edge.from]+edge.val<minDist[edge.to]){minDist[edge.to]=copy[edge.from]+edge.val;}}}if (minDist[dst]==Integer.MAX_VALUE){System.out.println("unreachable");}else {System.out.println(minDist[dst]);}}
}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;}
}

http://www.ppmy.cn/embedded/121605.html

相关文章

在 Qt 项目中使用 spdlog 的全攻略

目录 1. 准备工作&#xff1a;安装 spdlog 方法一&#xff1a;使用 CMake 的 FetchContent&#xff08;推荐&#xff09; 方法二&#xff1a;手动下载并添加到项目中 2. 在 Qt 项目中集成 spdlog a. 初始化 spdlog b. 在 Qt 的各个部分使用 spdlog 3. 基本使用示例 4. …

rabbitmq----数据管理模块

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 交换机数据管理管理的字段持久化管理类内存管理类申明交换机删除交换机获取指定交换机 队列数据管理管理的字段持久化管理类内存管理类申明/删除/获取指定队列获取所…

足球青训俱乐部管理:Spring Boot技术驱动

摘 要 随着社会经济的快速发展&#xff0c;人们对足球俱乐部的需求日益增加&#xff0c;加快了足球健身俱乐部的发展&#xff0c;足球俱乐部管理工作日益繁忙&#xff0c;传统的管理方式已经无法满足足球俱乐部管理需求&#xff0c;因此&#xff0c;为了提高足球俱乐部管理效率…

【MySQL】基本查询

目录 前言1. 插入1.1 指定列插入1.2 全列插入1.3 插入否则更新1.4 替换 2. 查询2.1 select2.1.1 全列查询2.1.2 指定列查询2.1.3 表达式查询2.1.4 结果去重2.1.5 插入查询结果 2.2 where2.2.1 比较和逻辑运算符2.2.2 条件查询 2.3 order by2.4 分页显示 3. 修改3.1 update 4. 删…

python如何显示数组

np.set_printoptions方法的相关属性&#xff1a; <span style"background-color:#272822"><span style"color:#f8f8d4">set_printoptions(precisionNone, thresholdNone, edgeitemsNone, linewidthNone, suppressNone, nanstrNone, infstrNo…

方舟开发框架(ArkUI)可运行 OpenHarmony、HarmonyOS、Android、iOS等操作系统

ArkUI 是华为开发的一套声明式 UI 开发框架&#xff0c;用于构建分布式应用界面。ArkUI-X 是对 ArkUI 框架的扩展&#xff0c;支持开发者使用一套代码构建支持多平台&#xff08;包括 OpenHarmony、HarmonyOS、Android、iOS&#xff09;的应用。 一、方舟开发框架的ArkUI-X Ark…

Bilibili视频如何保存到本地

Bilibili(哔哩哔哩)作为中国领先的视频分享平台之一&#xff0c;汇聚了大量的优质内容&#xff0c;从搞笑动画、综艺节目到专业教程&#xff0c;应有尽有。许多用户时常会遇到这样的需求&#xff1a;希望将视频保存到本地&#xff0c;方便离线观看或者保存珍藏。由于版权保护等…

【SQL】仅出现一次的最大数据

目录 语法 需求 示例 分析 代码 语法 SELECT MAX(salary) AS highest_salary FROM employees; MAX 语句是一种常用于数据库查询、编程语言以及数据分析中的函数&#xff0c;用于返回一组值中的最大值&#xff0c;可以结合 GROUP BY 子句使用 MAX 函数&#xff0c;以获取每…