class065 A星、Floyd、Bellman-Ford与SPFA【算法】

class065 A星、Floyd、Bellman-Ford与SPFA【算法】

2023-12-9 19:27:02

算法讲解065【必备】A星、Floyd、Bellman-Ford与SPFA

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

code1 A*算法模版

// A*算法模版(对数器验证)

package class065;import java.util.PriorityQueue;// A*算法模版(对数器验证)
public class Code01_AStarAlgorithm {// 0:上,1:右,2:下,3:左public static int[] move = new int[] { -1, 0, 1, 0, -1 };// Dijkstra算法// grid[i][j] == 0 代表障碍// grid[i][j] == 1 代表道路// 只能走上、下、左、右,不包括斜线方向// 返回从(startX, startY)到(targetX, targetY)的最短距离public static int minDistance1(int[][] grid, int startX, int startY, int targetX, int targetY) {if (grid[startX][startY] == 0 || grid[targetX][targetY] == 0) {return -1;}int n = grid.length;int m = grid[0].length;int[][] distance = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {distance[i][j] = Integer.MAX_VALUE;}}distance[startX][startY] = 1;boolean[][] visited = new boolean[n][m];PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[2] - b[2]);// 0 : 行// 1 : 列// 2 : 从源点出发到达当前点的距离heap.add(new int[] { startX, startY, 1 });while (!heap.isEmpty()) {int[] cur = heap.poll();int x = cur[0];int y = cur[1];if (visited[x][y]) {continue;}visited[x][y] = true;if (x == targetX && y == targetY) {return distance[x][y];}for (int i = 0, nx, ny; i < 4; i++) {nx = x + move[i];ny = y + move[i + 1];if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 1 && !visited[nx][ny]&& distance[x][y] + 1 < distance[nx][ny]) {distance[nx][ny] = distance[x][y] + 1;heap.add(new int[] { nx, ny, distance[x][y] + 1 });}}}return -1;}// A*算法// grid[i][j] == 0 代表障碍// grid[i][j] == 1 代表道路// 只能走上、下、左、右,不包括斜线方向// 返回从(startX, startY)到(targetX, targetY)的最短距离public static int minDistance2(int[][] grid, int startX, int startY, int targetX, int targetY) {if (grid[startX][startY] == 0 || grid[targetX][targetY] == 0) {return -1;}int n = grid.length;int m = grid[0].length;int[][] distance = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {distance[i][j] = Integer.MAX_VALUE;}}distance[startX][startY] = 1;boolean[][] visited = new boolean[n][m];// 0 : 行// 1 : 列// 2 : 从源点出发到达当前点的距离 + 当前点到终点的预估距离PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[2] - b[2]);heap.add(new int[] { startX, startY, 1 + f1(startX, startY, targetX, targetY) });while (!heap.isEmpty()) {int[] cur = heap.poll();int x = cur[0];int y = cur[1];if (visited[x][y]) {continue;}visited[x][y] = true;if (x == targetX && y == targetY) {return distance[x][y];}for (int i = 0, nx, ny; i < 4; i++) {nx = x + move[i];ny = y + move[i + 1];if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 1 && !visited[nx][ny]&& distance[x][y] + 1 < distance[nx][ny]) {distance[nx][ny] = distance[x][y] + 1;heap.add(new int[] { nx, ny, distance[x][y] + 1 + f1(nx, ny, targetX, targetY) });}}}return -1;}// 曼哈顿距离public static int f1(int x, int y, int targetX, int targetY) {return (Math.abs(targetX - x) + Math.abs(targetY - y));}// 对角线距离public static int f2(int x, int y, int targetX, int targetY) {return Math.max(Math.abs(targetX - x), Math.abs(targetY - y));}// 欧式距离public static double f3(int x, int y, int targetX, int targetY) {return Math.sqrt(Math.pow(targetX - x, 2) + Math.pow(targetY - y, 2));}// 为了测试public static int[][] randomGrid(int n) {int[][] grid = new int[n][n];for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (Math.random() < 0.3) {// 每个格子有30%概率是0grid[i][j] = 0;} else {// 每个格子有70%概率是1grid[i][j] = 1;}}}return grid;}// 为了测试public static void main(String[] args) {int len = 100;int testTime = 10000;System.out.println("功能测试开始");for (int i = 0; i < testTime; i++) {int n = (int) (Math.random() * len) + 2;int[][] grid = randomGrid(n);int startX = (int) (Math.random() * n);int startY = (int) (Math.random() * n);int targetX = (int) (Math.random() * n);int targetY = (int) (Math.random() * n);int ans1 = minDistance1(grid, startX, startY, targetX, targetY);int ans2 = minDistance2(grid, startX, startY, targetX, targetY);if (ans1 != ans2) {System.out.println("出错了!");}}System.out.println("功能测试结束");System.out.println("性能测试开始");int[][] grid = randomGrid(4000);int startX = 0;int startY = 0;int targetX = 3900;int targetY = 3900;long start, end;start = System.currentTimeMillis();int ans1 = minDistance1(grid, startX, startY, targetX, targetY);end = System.currentTimeMillis();System.out.println("运行dijskra算法结果: " + ans1 + ", 运行时间(毫秒) : " + (end - start));start = System.currentTimeMillis();int ans2 = minDistance2(grid, startX, startY, targetX, targetY);end = System.currentTimeMillis();System.out.println("运行A*算法结果: " + ans2 + ", 运行时间(毫秒) : " + (end - start));System.out.println("性能测试结束");}}

code2 P2910 [USACO08OPEN] Clear And Present Danger S

// Floyd算法模版(洛谷)
// 测试链接 : https://www.luogu.com.cn/problem/P2910
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下所有代码,把主类名改成Main,可以直接通过

package class065;// Floyd算法模版(洛谷)
// 测试链接 : https://www.luogu.com.cn/problem/P2910
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下所有代码,把主类名改成Main,可以直接通过import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;public class Code02_Floyd {public static int MAXN = 101;public static int MAXM = 10001;public static int[] path = new int[MAXM];public static int[][] distance = new int[MAXN][MAXN];public static int n, m, ans;// 初始时设置任意两点之间的最短距离为无穷大,表示任何路不存在public static void build() {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {distance[i][j] = Integer.MAX_VALUE;}}}public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));while (in.nextToken() != StreamTokenizer.TT_EOF) {n = (int) in.nval;in.nextToken();m = (int) in.nval;for (int i = 0; i < m; i++) {in.nextToken();path[i] = (int) in.nval - 1;}// 这道题给的图是邻接矩阵的形式// 任意两点之间的边权都会给定// 所以显得distance初始化不太必要// 但是一般情况下,distance初始化一定要做build();for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {in.nextToken();distance[i][j] = (int) in.nval;}}floyd();ans = 0;for (int i = 1; i < m; i++) {ans += distance[path[i - 1]][path[i]];}out.println(ans);}out.flush();out.close();br.close();}public static void floyd() {// O(N^3)的过程// 枚举每个跳板// 注意,跳板要最先枚举!跳板要最先枚举!跳板要最先枚举!for (int bridge = 0; bridge < n; bridge++) { // 跳板for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {// i -> .....bridge .... -> j// distance[i][j]能不能缩短// distance[i][j] = min ( distance[i][j] , distance[i][bridge] + distance[bridge][j])if (distance[i][bridge] != Integer.MAX_VALUE && distance[bridge][j] != Integer.MAX_VALUE&& distance[i][j] > distance[i][bridge] + distance[bridge][j]) {distance[i][j] = distance[i][bridge] + distance[bridge][j];}}}}}}

code3 787. K 站中转内最便宜的航班

// Bellman-Ford算法应用(不是模版)
// k站中转内最便宜的航班
// 有 n 个城市通过一些航班连接。给你一个数组 flights
// 其中 flights[i] = [fromi, toi, pricei]
// 表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi。
// 现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线
// 使得从 src 到 dst 的 价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1。
// 测试链接 : https://leetcode.cn/problems/cheapest-flights-within-k-stops/

package class065;import java.util.Arrays;// Bellman-Ford算法应用(不是模版)
// k站中转内最便宜的航班
// 有 n 个城市通过一些航班连接。给你一个数组 flights
// 其中 flights[i] = [fromi, toi, pricei]
// 表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi。
// 现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线
// 使得从 src 到 dst 的 价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1。
// 测试链接 : https://leetcode.cn/problems/cheapest-flights-within-k-stops/
public class Code03_BellmanFord {// Bellman-Ford算法// 针对此题改写了松弛逻辑,课上讲了细节public static int findCheapestPrice(int n, int[][] flights, int start, int target, int k) {int[] cur = new int[n];Arrays.fill(cur, Integer.MAX_VALUE);cur[start] = 0;for (int i = 0; i <= k; i++) {int[] next = Arrays.copyOf(cur, n);for (int[] edge : flights) {// a -> b , wif (cur[edge[0]] != Integer.MAX_VALUE) {next[edge[1]] = Math.min(next[edge[1]], cur[edge[0]] + edge[2]);}}cur = next;}return cur[target] == Integer.MAX_VALUE ? -1 : cur[target];}}

P3385 【模板】负环

// Bellman-Ford + SPFA优化模版(洛谷)
// 给定一个 n个点的有向图,请求出图中是否存在从顶点 1 出发能到达的负环
// 负环的定义是:一条边权之和为负数的回路。
// 测试链接 : https://www.luogu.com.cn/problem/P3385
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下所有代码,把主类名改成Main,可以直接通过

package class065;// Bellman-Ford + SPFA优化模版(洛谷)
// 给定一个 n个点的有向图,请求出图中是否存在从顶点 1 出发能到达的负环
// 负环的定义是:一条边权之和为负数的回路。
// 测试链接 : https://www.luogu.com.cn/problem/P3385
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下所有代码,把主类名改成Main,可以直接通过import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;public class Code04_SPFA {public static int MAXN = 2001;public static int MAXM = 6001;// 链式前向星建图需要public static int[] head = new int[MAXN];public static int[] next = new int[MAXM];public static int[] to = new int[MAXM];public static int[] weight = new int[MAXM];public static int cnt;// SPFA需要public static int MAXQ = 4000001;// 源点出发到每个节点的距离表public static int[] distance = new int[MAXN];// 节点被松弛的次数public static int[] updateCnt = new int[MAXN];// 哪些节点被松弛了放入队列public static int[] queue = new int[MAXQ];public static int l, r;// 节点是否已经在队列中public static boolean[] enter = new boolean[MAXN];public static void build(int n) {cnt = 1;l = r = 0;Arrays.fill(head, 1, n + 1, 0);Arrays.fill(enter, 1, n + 1, false);Arrays.fill(distance, 1, n + 1, Integer.MAX_VALUE);Arrays.fill(updateCnt, 1, n + 1, 0);}public static void addEdge(int u, int v, int w) {next[cnt] = head[u];to[cnt] = v;weight[cnt] = w;head[u] = cnt++;}public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));in.nextToken();int cases = (int) in.nval;for (int i = 0, n, m; i < cases; i++) {in.nextToken(); n = (int) in.nval;in.nextToken(); m = (int) in.nval;build(n);for (int j = 0, u, v, w; j < m; j++) {in.nextToken(); u = (int) in.nval;in.nextToken(); v = (int) in.nval;in.nextToken(); w = (int) in.nval;if (w >= 0) {addEdge(u, v, w);addEdge(v, u, w);} else {addEdge(u, v, w);}}out.println(spfa(n) ? "YES" : "NO");}out.flush();out.close();br.close();}// Bellman-Ford + SPFA优化的模版public static boolean spfa(int n) {distance[1] = 0;updateCnt[1]++;queue[r++] = 1;enter[1] = true;while (l < r) {int u = queue[l++];enter[u] = false;for (int ei = head[u], v, w; ei > 0; ei = next[ei]) {v = to[ei];w = weight[ei];if (distance[u] + w < distance[v]) {distance[v] = distance[u] + w;if (!enter[v]) {if (updateCnt[v]++ == n) {return true;}queue[r++] = v;enter[v] = true;}}}}return false;}}

2023-12-9 21:16:55

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/210116.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

两年外包生涯做完,感觉自己废了一半。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

laravel的ORM 对象关系映射

Laravel 中的 ORM&#xff08;Eloquent ORM&#xff09;是 Laravel 框架内置的一种对象关系映射系统&#xff0c;用于在 PHP 应用中与数据库进行交互。Eloquent 提供了一种优雅而直观的语法&#xff0c;使得开发者可以使用面向对象的方式进行数据库查询和操作。 定义模型&…

结合ColorUI组件开发微信小程序

1.自定义组件生命周期函数&#xff1a; Component({data: {},attached() {console.log("自定义组件生命周期函数 attached--先执行");this.getPos();},ready() {console.log("ready生命周期函数---在attached之后执行")},methods: {getPos() {var that th…

数据结构:位图、布隆过滤器以及海量数据面试题

位图、布隆过滤器以及海量数据面试题 1.位图1.1概念1.2实现1.3位图应用 2.布隆过滤器2.1布隆过滤器的提出2.2布隆过滤器的概念2.3布隆过滤器的查找2.4布隆过滤器的实现2.5布隆过滤器的删除2.6布隆过滤器的优点2.7布隆过滤器的缺点 3.海量数据面试题3.1哈希切分3.2位图应用3.3布…

如何成为前1%的程序员

如果你想成为前1%的程序员&#xff0c;你必须遵循1%的程序员做什么&#xff0c;了解其他99%的人不做什么。在现代&#xff0c;我们有各种学习平台&#xff0c;里面充满了与编程相关的视频、图文以及其他资料。 举例来说&#xff0c;我作为编程的初学者&#xff0c;去寻找路线图…

IDEA2023找不到add framework support怎么解决

问题: 我的idea版本是2023.01&#xff0c;新版idea右键项目没有Add Framework Support&#xff0c;help里面也找不到相关的。 从project structue的facets里面添加就行了&#xff0c;都是一样的。 1.依旧是新建一个项目 2.file-->project structure--->facets 左上角加…

Android studio如何安装ai辅助工具

引言 在没有翻墙的情况下&#xff0c;即单纯在公司打工&#xff0c;经测试&#xff0c;大部分ai工具都是使用不了的&#xff08;比如各种gpt,codeium,copilot&#xff09;&#xff0c;根本登录不了账号&#xff0c;但有一个国内的codegeex是可以使用的&#xff0c;在这里不对各…

Android app性能优化指南

Android应用性能优化指南 提高应用程序的性能以实现更流畅的用户体验和更高的可见度。 性能在任何应用程序的成功中发挥着重要的作用。为用户提供流畅无缝的体验应该是开发人员的重点。 应用程序大小 在用户开始使用我们的应用程序之前&#xff0c;他们需要下载应用程序并将…

DTCC2023大会-DBdoctor-基于eBPF观测数据库-附所有PPT下载链接

DTCC2023大会-DBdoctor-基于eBPF观测数据库-附所有PPT下载链接 8月16日—18日,第14届中国数据库技术大会(DTCC-2023)在北京国际会议中心举行。聚好看在大会上首次发布基于eBPF观测数据库性能的产品DBdoctor&#xff0c;受到了业界广泛的关注。近期几位业内同仁过来要大会的PPT…

2024考研数学二备考历程

GoodNotesGoodNotes apphttps://share.goodnotes.com/s/bhsraJMZ6OJwuYJb3OWnzP

C/C++之输入输出

文章目录 一.C语言的输入输出1.printfi. 输出整数ii. 浮点数iii.字符 & 字符串 2.scanfi.整数ii.浮点数iii. 字符 & 字符串 3.特殊用法i. * 的应用ii. %n 的应用iii. %[] 的应用 二.C中的输入输出1.couti. 缓冲区&#xff08;buffer&#xff09;ii. cout之格式化输出 2…

Proteus仿真--串口发送数据到2片8×8点阵屏滚动显示

本文介绍2片88点阵屏滚动显示设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 仿真运行视频 Proteus仿真--1602LCD显示电话拨号键盘按键实验&#xff08;仿真文件程序&#xff09; 附完整Proteus仿真资料代码资料 链接&#xff1a;https://pan.baidu…

使用C语言操作kafka ---- librdkafka

1 安装librdkafka git clone https://github.com/edenhill/librdkafka.git cd librdkafka git checkout v1.7.0 ./configure make sudo make install sudo ldconfig 在librdkafka的examples目录下会有示例程序。比如consumer的启动需要下列参数 ./consumer <broker> &…

一对一聊天程序

package untitled1.src;import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import java.net.*;public class MyServer extends JFrame{private ServerSocket server; // 服务器套接字pri…

【漏洞复现】华脉智联指挥调度平台/xml_edit/fileread.php文件读取漏洞

Nx01 产品简介 深圳市华脉智联科技有限公司&#xff0c;融合通信系统将公网集群系统、专网宽带集群系统、不同制式、不同频段的短波/超短波对讲、模拟/数字集群系统、办公电话系统、广播系统、集群单兵视频、视频监控系统、视频会议系统等融为一体&#xff0c;集成了专业的有线…

第一课【习题】HarmonyOS应用/元服务上架

元服务发布的国家与地区仅限于“中国大陆” 编译打包的软件包存放在项目目录build > outputs > default下 创建应用时&#xff0c;应用包名需要和app.json5或者config.json文件中哪个字段保持一致&#xff1f; 发布应用时需要创建证书&#xff0c;证书类型选择什么…

web前端实现LED功能、液晶显示时间、数字

MENU 效果演示html部分JavaScript部分css部分 效果演示 html部分 <div id"app"><!-- 页面 --><div class"time-box"><!-- 时 --><div class"house-box"><bit-component :num"houseTem"></bit…

使用cmake构建Qt6.6的qt quick项目,添加应用程序图标的方法

最近&#xff0c;在学习qt的过程中&#xff0c;遇到了一个难题&#xff0c;不知道如何给应用程序添加图标&#xff0c;按照网上的方法也没有成功&#xff0c;后来终于自己摸索出了一个方法。 1、准备一张图片作为图标&#xff0c;保存到工程目录下面&#xff0c;如logo.ico。 …

mybatis的快速入门以及spring boot整合mybatis(二)

需要用到的SQL脚本&#xff1a; CREATE TABLE dept (id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT ID, 主键,name varchar(10) NOT NULL UNIQUE COMMENT 部门名称,create_time datetime DEFAULT NULL COMMENT 创建时间,update_time datetime DEFAULT NULL COMMENT 修改…

低多边形建筑3D模型纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时&#xff0c;有几种不同的风格&#xf…