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

代码随想录算法训练营第六十天|图论part10

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

文章讲解:代码随想录

为啥要优化?

因为在松弛的过程中 做了很多无用功

所以用队列来记录需要松弛的边

#include <iostream>
#include <vector>
#include <climits>
#include <queue>
#include <list>struct Edge{int s,t;int val;Edge(int _s,int _t,int _val):s(_s),t(_t),val(_val){}
};using namespace std;
int main(){int n,m;cin>>n>>m;vector<list<Edge>>grid(n+1);vector<bool>isInQueue(n+1,false);vector<int>minDist(n+1,INT_MAX);queue<int>myQueue;while(m--){int s,t,v;cin>>s>>t>>v;grid[s].push_back(Edge(s,t,v));}int start=1;int end=n;minDist[start]=0;myQueue.push(start);while(!myQueue.empty()){int cur=myQueue.front();myQueue.pop();isInQueue[cur]=false;//出队后需标记const auto& edges=grid[cur];for(auto& edge:edges){int s=edge.s;int t=edge.t;int val=edge.val;if(minDist[s]==INT_MAX)continue;minDist[t]=min(minDist[s]+val,minDist[t]);if(!isInQueue[t]){myQueue.push(t);isInQueue[t]=true;//入队后需标记}}}if(minDist[end]!=INT_MAX)cout<<minDist[end];else cout<<"unconnected";}

bellman_ford之判断负权回路

题目链接:95. 城市间货物运输 II

文章讲解:代码随想录

思路:

普通版的福特算法,考虑第n次松弛是否会出现更短的路径。出现就标记

#include <iostream>
#include <vector>
#include <climits>
using namespace std;int main(){//数据读取int n,m;cin>>n>>m;vector<vector<int>>grid;vector<int>minDist(n+1,INT_MAX);while(m--){int s,t,v;cin>>s>>t>>v;grid.push_back({s,t,v});}int start=1;int end=n;minDist[start]=0;bool flag=false;for(int i=1;i<=n;i++){for(int j=0;j<grid.size();j++){int s=grid[j][0];int t=grid[j][1];int val=grid[j][2];if(minDist[s]==INT_MAX)continue;if(i<n){minDist[t]=min(minDist[t],minDist[s]+val);}else{if(minDist[s]+val<minDist[t]) flag=true;}}}//输出if(flag){cout<<"circle";return 0;} if(minDist[end]!=INT_MAX)cout<<minDist[end];else cout<<"unconnected";
}

队列优化版的福特算法 ,统计节点入队次数。如果节点入队次数超过n,说明出现环。

#include <iostream>
#include <vector>
#include <climits>
#include <queue>
#include <list>struct Edge{int s,t;int val;Edge(int _s,int _t,int _val):s(_s),t(_t),val(_val){}
};using namespace std;
int main(){//数据读取int n,m;cin>>n>>m;vector<list<Edge>>grid(n+1);vector<bool>isInQueue(n+1,false);vector<int>minDist(n+1,INT_MAX);queue<int>myQueue;while(m--){int s,t,v;cin>>s>>t>>v;grid[s].push_back(Edge(s,t,v));}int start=1;int end=n;minDist[start]=0;myQueue.push(start);bool flag=false;vector<int>count(n+1,0);//统计每个节点的入队数量while(!myQueue.empty()){int cur=myQueue.front();myQueue.pop();isInQueue[cur]=false;//出队后需标记const auto& edges=grid[cur];for(auto& edge:edges){int s=edge.s;int t=edge.t;int val=edge.val;if(minDist[s]==INT_MAX)continue;minDist[t]=min(minDist[s]+val,minDist[t]);if(!isInQueue[t]){myQueue.push(t);isInQueue[t]=true;//入队后需标记count[t]++;if(count[t]==n){flag=true;while(!myQueue.empty()){myQueue.pop();}//这里是防止再次进入while循环 break;}}}}//输出if(flag){cout<<"circle";return 0;} if(minDist[end]!=INT_MAX)cout<<minDist[end];else cout<<"unconnected";}

bellman_ford之单源有限最短路

题目链接:96. 城市间货物运输 III

文章讲解:代码随想录

#include <iostream>
#include <vector>
#include <climits>using namespace std;int main(){int n,m;cin>>n>>m;vector<vector<int>>grid;while(m--){int s,t,v;cin>>s>>t>>v;grid.push_back({s,t,v});}int start,end,k;cin>>start>>end>>k;vector<int>minDist(n+1,INT_MAX);minDist[start]=0;for(int i=1;i<=k+1;i++){auto copy_minDist=minDist;for(int j=0;j<grid.size();j++){int s=grid[j][0];int t=grid[j][1];int val=grid[j][2];if(copy_minDist[s]==INT_MAX)continue;minDist[t]=min(copy_minDist[s]+val,minDist[t]);}}if(minDist[end]==INT_MAX)cout<<"unreachable";else cout<<minDist[end];}

本题的关键是对松弛的次数有严格要求,不能多松弛。

关键点1:

松弛此时为k+1,

关键点2:

每轮松弛都要基于上一轮的minDist数组,所以要复制一份

http://www.lryc.cn/news/616375.html

相关文章:

  • 【Nginx②】 | Nginx部署前端静态文件指南(基于虚拟机环境)
  • 浏览器CEFSharp88+X86+win7 之多页面展示(四)
  • NodeJs学习日志(4):路由合并_环境配置_常用文件目录
  • element-ui el-progress在有小数的情况下,会换行显示。解决不换行的问题。
  • iceberg安装部署
  • Rust面试题及详细答案120道(11-18)-- 控制流与函数
  • vulnhub-Drippingblues靶机
  • 通过Certbot自动申请更新HTTPS网站的SSL证书
  • 瑞芯微 RK3588 平台驱动开发 学习计划
  • CST支持对哪些模型进行特征模仿真?分别有哪些用于特征模分析的求解器?
  • C语言——深入理解指针(二)
  • 【东枫科技】FR3 可扩展测试平台,适用于 6G 研究与卫星通信,高达 1.6 GHz 的带宽
  • 【秋招笔试】2025.08.09美团秋招算法岗机考真题-第三题
  • Python 的浅拷贝 vs 深拷贝(含嵌套可变对象示例与踩坑场景)
  • OpenGL VAO 概念、API 和示例
  • 每日一题:使用栈实现逆波兰表达式求值
  • TypeScript中的type和interface的区别是什么?
  • 从街亭失守看管理
  • WAV音频数据集MFCC特征提取处理办法
  • 【MySQL——第三章 :MySQL库表操作】
  • 如何选择适合自己电商业务的 API?​
  • DBAPI 实现不同角色控制查看表的不同列
  • 七、CV_模型微调
  • 使用快捷键将当前屏幕内容滚动到边缘@首行首列@定位到第一行第一个字符@跳转到4个角落
  • Knuth‘s TwoSum Algorithm 原理详解
  • 每日任务day0810:小小勇者成长记之武器精炼
  • 机器学习 DBScan
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-关于我们
  • 人大地平线新国立单目具身导航新范式!MonoDream:基于全景想象的单目视觉语言导航
  • 周学会Matplotlib3 Python 数据可视化-绘制折线图(Lines)