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

力扣算法刷题 Day 64 Floyd算法 A* 算法 总结篇

Floyd算法

算法原理

Floyd算法解决多源最短路径问题。本质用动态规划。如,mindis[1][5] = mindis[1][3] + mindis[3][5]

算法流程

dp五部曲:

  1. dp数组含义: dp[i][j]表示从i到j的最短距离。
  2. 递推式:dp[i][j] = min(dp[i][k] + dp[k][j]), k需要遍历
  3. 初始化:dp[i][i] = 0,如果i到j有边,dp[i][j] = 权值,否则为正无穷
  4. 遍历顺序:三层循环
#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;constlonglongINF=1e18;voidfloyd(vector<vector<longlong>>&dist){intn=dist.size();for(intk=0;k<n;k++){// 中转点for(inti=0;i<n;i++){// 起点for(intj=0;j<n;j++){// 终点if(dist[i][k]==INF||dist[k][j]==INF){continue;}dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);}}}}intmain(){intn,m;cin>>n>>m;vector<vector<longlong>>dist(n,vector<longlong>(n,INF));// 自己到自己距离为 0for(inti=0;i<n;i++){dist[i][i]=0;}// 输入 m 条边:u v w// 表示 u 到 v 的边权为 wfor(inti=0;i<m;i++){intu,v;longlongw;cin>>u>>v>>w;dist[u][v]=min(dist[u][v],w);// 如果是无向图,加上这一句// dist[v][u] = min(dist[v][u], w);}floyd(dist);// 输出最短距离矩阵for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(dist[i][j]==INF){cout<<"INF ";}else{cout<<dist[i][j]<<" ";}}cout<<endl;}return0;}

当需要打印出所有路径时:
优化:开两个数组,一个存距离,一个存下一跳。path[i][j]表示从i到j的路径上,以i为起点的下一跳是什么。还原时不断寻找下一跳为起点的path。如:path[1][4] = 2 -> path[2][4] = 3-> path[3][4] = 4 ,到达终点,停止。

#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;constlonglongINF=1e18;voidfloydWithPath(vector<vector<longlong>>&dist,vector<vector<int>>&path){intn=dist.size();for(intk=0;k<n;k++){// 中转点for(inti=0;i<n;i++){// 起点for(intj=0;j<n;j++){// 终点if(dist[i][k]==INF||dist[k][j]==INF){continue;}if(dist[i][k]+dist[k][j]<dist[i][j]){dist[i][j]=dist[i][k]+dist[k][j];// i 到 j 的下一跳,应该等于 i 到 k 的下一跳path[i][j]=path[i][k];}}}}}vector<int>getPath(intstart,intend,constvector<vector<int>>&path){vector<int>result;if(path[start][end]==-1){returnresult;// 不可达}result.push_back(start);while(start!=end){start=path[start][end];result.push_back(start);}returnresult;}intmain(){intn,m;cin>>n>>m;vector<vector<longlong>>dist(n,vector<longlong>(n,INF));vector<vector<int>>path(n,vector<int>(n,-1));// 初始化for(inti=0;i<n;i++){dist[i][i]=0;path[i][i]=i;}// 输入 m 条边:u v w// 表示 u 到 v 的边权为 wfor(inti=0;i<m;i++){intu,v;longlongw;cin>>u>>v>>w;if(w<dist[u][v]){dist[u][v]=w;path[u][v]=v;}// 如果是无向图,加上下面这一段/* if (w < dist[v][u]) { dist[v][u] = w; path[v][u] = u; } */}floydWithPath(dist,path);// 输出最短距离矩阵cout<<"Shortest distance matrix:"<<endl;for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(dist[i][j]==INF){cout<<"INF ";}else{cout<<dist[i][j]<<" ";}}cout<<endl;}// 查询一条路径intstart,end;cout<<"Input start and end: ";cin>>start>>end;vector<int>shortestPath=getPath(start,end,path);if(shortestPath.empty()){cout<<"No path from "<<start<<" to "<<end<<endl;}else{cout<<"Shortest path: ";for(inti=0;i<shortestPath.size();i++){if(i>0)cout<<" -> ";cout<<shortestPath[i];}cout<<endl;cout<<"Shortest distance: "<<dist[start][end]<<endl;}return0;}

A* 算法

算法原理

改良版的BFS。区别于穷举,A* 根据启发式函数有选择的进行遍历。给每一个节点一个权值,Key = 起点到当前节点的距离 + 当前节点到终点的距离。维护BFS队列,每次从中取权值最小的节点。

#include<iostream>#include<queue>#include<string.h>usingnamespacestd;intmoves[1001][1001];intdir[8][2]={-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2};intb1,b2;// F = G + H// G = 从起点到该节点路径消耗// H = 该节点到终点的预估消耗structKnight{intx,y;intg,h,f;booloperator<(constKnight&k)const{// 重载运算符, 从小到大排序returnk.f<f;}};priority_queue<Knight>que;intHeuristic(constKnight&k){// 欧拉距离return(k.x-b1)*(k.x-b1)+(k.y-b2)*(k.y-b2);// 统一不开根号,这样可以提高精度}voidastar(constKnight&k){Knight cur,next;que.push(k);while(!que.empty()){cur=que.top();que.pop();if(cur.x==b1&&cur.y==b2)break;for(inti=0;i<8;i++){next.x=cur.x+dir[i][0];next.y=cur.y+dir[i][1];if(next.x<1||next.x>1000||next.y<1||next.y>1000)continue;if(!moves[next.x][next.y]){moves[next.x][next.y]=moves[cur.x][cur.y]+1;// 开始计算Fnext.g=cur.g+5;// 统一不开根号,这样可以提高精度,马走日,1 * 1 + 2 * 2 = 5next.h=Heuristic(next);next.f=next.g+next.h;que.push(next);}}}}intmain(){intn,a1,a2;cin>>n;while(n--){cin>>a1>>a2>>b1>>b2;memset(moves,0,sizeof(moves));Knight start;start.x=a1;start.y=a2;start.g=0;start.h=Heuristic(start);start.f=start.g+start.h;astar(start);while(!que.empty())que.pop();// 队列清空cout<<moves[b1][b2]<<endl;}return0;}

图论总结

图的定义,图的存储,图的遍历,并查集(解决快速判断元素是否属于一个集合的问题,压缩路径),图的连通(最小生成树,prim,kasul算法),拓扑排序(解决线性依赖问题)最短路径(单源有向正权,单源有向负权,多源)
添加链接描述

http://www.jsqmd.com/news/786037/

相关文章:

  • 基于本地Markdown与AI的跨平台笔记系统:打通OpenClaw与Claude Code
  • 可变剪接研究方法汇总(2026 最新)|基于 Nature Reviews Genetics 顶刊综述
  • Taotoken用量看板如何帮助团队透明化管理AI成本
  • 为Claude Code配置Taotoken以解决访问不稳定与Token不足问题
  • AI教材生成时代来临!低查重工具让教材编写不再烦恼!
  • 测试89测试89测试89测试89测试89
  • 泰山派3M-RK3576-Linux内核驱动教程-Linux驱动基础-设备模型与sysfs-创建sysfs属性文件
  • 显示技术进入像素创新时代,TCL华星吹响产业技术落地的号角
  • 科学AI中的不确定性量化:从贝叶斯推理到深度学习实践
  • 收藏!大厂成立AI部门,普通人也能抓住高薪机遇,小白也能学大模型!
  • 使用OpenClaw工具时如何通过Taotoken CLI一键写入配置
  • 从零开始为 ATB 库开发一个 Add 算子
  • HexHub 全面解析:高颜值全能型数据库+SSH+Docker管理工具,开发者效率神器
  • H5页面的几种 支付方式
  • AI驱动PDE逆问题求解:从物理约束到工程设计的范式革新
  • 微深节能 龙门吊行车定位及控制系统 格雷母线
  • x.com 提示:启用 JavaScript 或切换浏览器,禁用隐私扩展程序以正常使用
  • DownKyi哔哩下载姬:B站视频下载完整教程与使用指南
  • 南宁家长真实评价:用了3年家教总动员,最看重的不是价格而是这两点 - 教育快讯速递
  • 敢于冲刷那些虚浮的“人设”
  • 2026漏洞挖掘实战指南:从零基础到独立挖到第一个漏洞,拿下第一桶金!
  • 生成式AI与LLM恶意应用:深度伪造与社会操纵的防御实战
  • [极客大挑战 2019]Havefun
  • T1-Super-AI:构建多智能体协作框架,从原理到实战
  • 基于SVR与特征选择的系外行星半径预测:从数据清洗到模型调优实战
  • 机器学习项目成功基石:数据就绪度评估与可视化分析实战指南
  • CANN/pypto设置立方体切片形状
  • 收藏!AI浪潮下,大龄程序员如何逆袭,掌握未来核心竞争力!
  • 梁耀烽:苦难也有童话 十亿分之一的奇迹
  • OpenClaw Client:构建现代化AI Agent Web控制台的完整指南