最短路相关思想总结

dijkstra—所有边均为正权边

1.稠密图

dijkstra()1

算法思想

将所有的点读入邻接表
外层n次循环
每次找到最近的点,记录这个点的访问状态,使用这个点对其他的点进行更新,最后返回最短路
为什么要记录每个点的状态?我不能重复搜这个点吗???
我们的目的是找到最短路径,不能知道原地转,需要向前走,我们不能走回头路

算法步骤:

#include<iostream>
#include<cstring>
using namespace std;
const int N=510;
int g[N][N],d[N],st[N];
//st记录是否被访问过
int n,m;int dijkstra()
{d[1]=0;for(int i=1;i<=n;i++){int t=-1;for(int j=1;j<=n;j++)if(!st[j]&&(t==-1||d[t]>d[j]))t=j;st[t]=true;for(int j=1;j<=n;j++)if(d[j]>d[t]+g[t][j])d[j]=d[t]+g[t][j];}return d[n];
}
int main()
{cin>>n>>m;memset(d,0x3f,sizeof(d));memset(g,0x3f,sizeof(g));while(m--){int a,b,c;cin>>a>>b>>c;g[a][b]=min(g[a][b],c);}int t=dijkstra();if(t==0x3f3f3f3f) puts("-1");else printf("%d\n",t);return 0;
}

2.稀疏图

dijkstra()2

算法思想

将所有的点读入,因为是邻接表,还是正权边—>dijkstra算法
dijkstra算法需要找到每次的最短的边,所以需要使用优先队列来快速取出最短的距离

算法步骤以及实现

#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int N=3e5+10;
int h[N],e[N],ne[N],idx,w[N],d[N],st[N];
//st表示是否被搜过
int n,m;
typedef pair<int,int> PII;void add(int a,int b,int c)
{e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
int dijkstra()
{//每次拿出最近的点,所以排序的时候需要将距离进行排序//监测他是否被搜过//如果被搜过直接跳过,没有就进行更新//后面被更新的点,没有被搜过那么将他放进堆中priority_queue<PII,vector<PII>,greater<PII>> p;d[1]=0;p.push({0,1});while(p.size()){auto t=p.top();p.pop();int pos=t.second,dis=t.first;if(st[pos]) continue;//如果被搜过就不在搜了st[pos]=true;//如果被搜索过了,更新成truefor(int i=h[pos];~i;i=ne[i]){int j=e[i];if(d[j]>dis+w[i]) d[j]=dis+w[i],p.push({d[j],j});}}return d[n];
}
int main()
{cin>>n>>m;//读入数据并初始化memset(d,0x3f,sizeof(d));memset(h,-1,sizeof(h));while(m--){int a,b,c;cin>>a>>b>>c;add(a,b,c);//有向图}int t=dijkstra();if(t==0x3f3f3f3f) t=-1;printf("%d\n",t);return 0;
}

bellman_fold—存在负权边

在这里插入图片描述

算法思想

我们对边进行存储,对所有的边进行访问,使用上次的距离进行更新

算法步骤以及实现

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10010;
struct Edge
{int a,b,c;
}edge[N];
int n,m,k;
int d[N],last[N];//last记录上次的距离int bellman_fold()
{//在不超过k次的情况下,进行搜索for(int i=0;i<k;i++){//每次记录上次的距离memcpy(last,d,sizeof(d));for(int j=0;j<m;j++){auto e=edge[j];d[e.b]=min(d[e.b],last[e.a]+e.c);}}return d[n];
}
int main()
{cin>>n>>m>>k;//使用结构体进行存储for(int i=0;i<m;i++) cin>>edge[i].a>>edge[i].b>>edge[i].c;//对距离进行初始化memset(d,0x3f,sizeof(d));d[1]=0;int t=bellman_fold();if(t>0x3f3f3f3f/2) puts("impossible");else printf("%d",t);return 0;
}

spfa算法—存在负权边

在这里插入图片描述

算法思想

spfa是对bellman_fold算法的升级,将出发点加入队列中(队列中的点都是变化的点)
持续从队列中取出一个点,记录这个点没在队列中,判断他的临边是否需要改变如果改变->加入队列并记录在队列中的状态

算法步骤以及实现

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=1e5+10;
int h[N],e[N],ne[N],idx,d[N],st[N],w[N];
//st表示是否在队列中
int n,m;void add(int a,int b,int c)
{e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
int spfa()
{d[1]=0;queue<int> q;q.push(1);st[1]=true;while(q.size()){int t=q.front();q.pop();st[t]=false;//表示没有在队列中for(int i=h[t];~i;i=ne[i]){int j=e[i];if(d[j]>d[t]+w[i])//表示需要更新的点,将更新的点加入队列中{d[j]=d[t]+w[i];if(!st[j])//将没有在队列中的点加入队列中{q.push(j);st[j]=true;}}}}return d[n];
}
int main()
{memset(h,-1,sizeof(h));cin>>n>>m;for(int i=0;i<m;i++) {int a,b,c;cin>>a>>b>>c;add(a,b,c);}memset(d,0x3f,sizeof(d));int t=spfa();if(t==0x3f3f3f3f) puts("impossible");else printf("%d\n",t);return 0;
}

堆优化版的spfa算法

在这里插入图片描述

算法思想

spfa算法是bellman_fold算法的进化
判负环的基本方法是spfa
将数据读入,因为不知道那个点是负环的起点所有每个点都有可能–>将所有点加入队列,如果距离更小,更新距离并将此点加入队列

算法步骤以及实现

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=1e4+10;
//d不需要进行初始化,如果存在负权边那么一定会改变
int d[N],st[N],w[N],h[N],e[N],ne[N],idx,cnt[N];
int n,m;void add(int a,int b,int c)
{e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
bool spfa()
{queue<int> q;for(int i=1;i<=n;i++) q.push(i),st[i]=true;while(q.size()){int t=q.front();q.pop();st[t]=false;for(int i=h[t];~i;i=ne[i]){int j=e[i];if(d[j]>d[t]+w[i]){d[j]=d[t]+w[i];cnt[j]=cnt[t]+1;//当点的个数大于等于n的时候,证明已经是出现负环了if(cnt[j]>=n) return true;if(!st[j]) {st[j]=true;q.push(j);}}}}return false;
}
int main()
{cin>>n>>m;memset(h,-1,sizeof(h));//memset(d,0x3f,sizeof(d));while(m--){int a,b,c;cin>>a>>b>>c;add(a,b,c);}if(spfa()) puts("Yes");else puts("No");return 0;
}

floyd算法—多源汇—不存在负权回路

在这里插入图片描述

算法思想

稠密图,使用邻接矩阵来存
因为是多源汇,所有每个点都可能使起点,所以在初始化的时候需要注意将每个点的自己到自己的距离初始化为0

算法步骤以及实现

#include<cstring>
#include<iostream>
using namespace std;
const int N=210,INF=0x3f3f3f3f;
int d[N][N];
int n,m,k;void floyd()
{for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
int main()
{cin>>n>>m>>k;//多源汇for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) if(i==j) d[i][j]=0;else d[i][j]=INF;while(m--){int a,b,c;cin>>a>>b>>c;d[a][b]=min(d[a][b],c);}floyd();while(k--){int a,b;cin>>a>>b;if(d[a][b]>INF/2) puts("impossible");else printf("%d\n",d[a][b]);}return 0;
}
以上是我的一些暂时的理解,可能有些不恰当的地方,
以后如果发现了更好的理解方式,会回来的。

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

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

相关文章

sysstat安装与使用

官方文档 http://sebastien.godard.pagesperso-orange.fr/documentation.html sysstat安装 1.下载源码 https://github.com/sysstat/sysstat 2.编译安装 tar xvf sysstat-xxx.tar.gz ./configure make -j 16 make install3.测试 iostatsysstat使用 sysstat 包包含许多商…

【css】属性选择器

有些场景中需要在相同元素中获取具有特定属性的元素&#xff0c;比如同为input&#xff0c;type属性有text、button&#xff0c;可以通过属性选择器设置text和button的不同样式。 代码&#xff1a; <style> input[typetext] {width: 150px;display: block;margin-bottom…

大连交通大学813软件工程考研习题

1.什么是软件生存周期模型?有哪些主要模型? 生存周期模型&#xff1a;描述软件开发过程中各种活动如何执行的模型。对软件开发提供强有力的支持&#xff0c;为开发过程中的活动提供统一的政策保证&#xff0c;为参与开发的人员提供帮助和指导&#xff0c;是软件生存周期模型…

An unexpected error has occurred. Conda has prepared the above report

今日在服务器上创建anaconda虚拟环境的时候&#xff0c;出现了如下报错 An unexpected error has occurred. Conda has prepared the above report 直接上解决方案 在终端中输入如下指令 conda config --show-sources 如果出现以下提示&#xff0c;说明多了一个文件 输入以下…

【网络安全】等保测评系列预热

【网络安全】等保测评系列预热 前言1. 什么是等级保护&#xff1f;2. 为什么要做等保&#xff1f;3. 路人甲疑问&#xff1f; 一、等保测试1. 渗透测试流程1.1 明确目标1.2 信息搜集1.3 漏洞探索1.4 漏洞验证1.5 信息分析1.6 获取所需1.7 信息整理1.8 形成报告 2. 等保概述2.1 …

激光与光电子学进展, 2023 | 非视域成像技术研究进展

注1&#xff1a;本文系“计算成像最新论文速览”系列之一&#xff0c;致力于简洁清晰地介绍、解读非视距成像领域最新的顶会/顶刊论文(包括但不限于 Nature/Science及其子刊; CVPR, ICCV, ECCV, SIGGRAPH, TPAMI; Light‑Science & Applications, Optica 等)。 本次介绍的论…

Java【Spring】使用注解, 更简单的存储和获取 Bean

文章目录 前言一、存储 Bean1, 配置文件2, 五大类注解Bean 的命名规则 3, 方法注解Bean 的命名规则 二、获取 Bean1, 属性注入2, Setter 注入3, 构造方法注入4, Autowired 和 Resource 的区别5, 同一个类型的多个 Bean 注入问题 总结 前言 各位读者好, 我是小陈, 这是我的个人主…

架构训练营学习笔记:5-2 负载均衡架构

多级负载架构 设计关键点 性能需求、维护复杂度之间做取舍。 一可以去掉F5、LVS &#xff1a; F5 是成本较高&#xff0c;LVS 是复杂&#xff0c;对于性能没那么高需求&#xff0c;可以去掉。 二 去掉ng: 服务网关服务 适应于初创公司快速验证&#xff0c;内部的 小系统…

【uniapp】uniapp打包H5(网页端):

文章目录 一、设置appid&#xff1a;二、设置router&#xff1a;三、打包&#xff1a;【1】[CLI 发行uni-app到H5&#xff1a;https://hx.dcloud.net.cn/cli/publish-h5](https://hx.dcloud.net.cn/cli/publish-h5)【2】HBuilderX 四、最终效果&#xff1a; 一、设置appid&…

Zebec Protocol ,不止于 Web3 世界的 “Paypal”

Paypal是传统支付领域的巨头企业&#xff0c;在北美支付市场占有率约为77%以上。从具体的业务数据看&#xff0c;在8月初&#xff0c;Paypal公布的2023年第二季度财报显示&#xff0c;PayPal第二季度净营收为73亿美元&#xff0c;净利润为10.29亿美元。虽然Paypal的净利润相交去…

buildroot使用介绍

buildroot是Linux平台上一个构建嵌入式Linux系统的框架。整个Buildroot是由Makefile脚本和Kconfig配置文件构成的。你可以和编译Linux内核一样&#xff0c;通过buildroot配置&#xff0c;menuconfig修改&#xff0c;编译出一个完整的可以直接烧写到机器上运行的Linux系统软件(包…

提速Rust编译器!

Nethercote是一位研究Rust编译器的软件工程师。最近&#xff0c;他正在探索如何提升Rust编译器的性能&#xff0c;在他的博客文章中介绍了Rust编译器是如何将代码分割成代码生成单元&#xff08;CGU&#xff09;的以及rustc的性能加速。 他解释了不同数量和大小的CGU之间的权衡…