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

C++ 最短路SPFA

算法描述:

对于图 G = <V, E>,源点为s,d[i]表示s到i的最短路。

(1)利用一个先进先出的队列来保存待松弛的节点,每次取出队首u,并且枚举从u出发的所有点(u,v),进行松弛操作:

         d[v] = min(d[v], d[u] + w(u, v))

(2)然后判断v在不在队列中,如果不在就将v放入队列中。这样不断从队列中取出结点来进行松弛操作,直到队列为空为止

代码分析:

第一步,定义边的数据结构 Edge(v, w)

第二步,边的添加,

function addEdge(edges[maxn], u, v, w)

  edges[u].append(Edge(v, w))

第三步,建图

addEdge(edges, u1, v1, w1)

addEdge(edges, u2, v2, w2)

...

第四步,SPFA框架代码

function SPFA(n, s, edges[maxn],  d[maxn], visited[maxn])

  q = Queue()

  inq = {} 

  SPFAinit(n, s, d, visited, q, inq)

  while(not q.empty())

    u = q.front()

    q.pop()

    inq.remove(u)

    if visited[u]++ > n

      return true

    SPFArelax(u, edges, d, q, inq)

return false

第五步,SPFA初始化

function SPFAinit(n, s, d[maxn], visited[maxn], q, inq)

  for i -> (0, n-1)

    d[i] = inf

    visited[i] = 0

  d[s] = 0

  visited[s] = 1

  q.push(s)

  inq.add(s)

第六步,实现松弛操作

function SPFARelax(u, edges[maxn], d[maxn], q, inq)

  for i-> (0, edges[u].size() - 1)

    v, w = edges[u][i]

    if d[u] + w < d[v]

      d[v] = d[u] + w

      if not inq.has(v)

        q.push(v)

        inq.add(v)

SPFA的最长时间复杂度为km,k为常数,m为边数

代码练习,对应蓝桥云课 路径 代码见下

#include <iostream>
#include <vector>
#include <queue>
using namespace std;#define maxn 2022
#define maxm (2022*2*22)
#define eType int
#define inf 1000000000
#define longOrShortpath <struct EDGE{int v;eType w;EDGE() {}EDGE(int _v, eType _w){v = _v;w = _w;}
};void initEdges(int n, vector<EDGE> edges[maxn]){for(int i=0; i<=n; ++i){edges[i].clear();}
}void addEdge(vector<EDGE> edges[maxn], int u, int v, eType w){edges[u].push_back(EDGE(v, w));
}void SPFAinit(int n, int s, eType dist[maxn], queue<int>& q, bool inqueue[maxn]){for(int i=0; i<=n; ++i){dist[i] = (i == s) ? 0:inf;inqueue[i] = false;}inqueue[s] = true;q.push(s);}void SPFAupdate(vector<EDGE> edges[maxn], int u, eType dist[maxn], queue<int>& q, bool inqueue[maxn]){for(int i=0; i<edges[u].size(); ++i){int v = edges[u][i].v;eType w = edges[u][i].w;if(dist[u] + w longOrShortpath dist[v]){dist[v] = dist[u] + w;if(!inqueue[v]){inqueue[v] = true;q.push(v);}}}
}void SPFA(vector<EDGE> edges[maxn], int n, int s, eType dist[maxn]){queue<int> q;bool inqueue[maxn];SPFAinit(n, s, dist, q, inqueue);while(!q.empty()){int u = q.front();q.pop();inqueue[u] = false;SPFAupdate(edges, u, dist, q, inqueue);}
}
vector<EDGE> edges[maxn];
eType dist[maxn];int gcd(int a, int b){return !b ? a:gcd(b, a%b);
}int lcm(int a, int b){return a/gcd(a, b) * b;
}int main()
{int n = 2021;initEdges(n, edges);for(int i=1; i <= n; ++i){for(int j=1; j - i <= 21; ++j){if(i-j > 21) continue;if (j > n) break;addEdge(edges, i, j, lcm(i, j));}}SPFA(edges, n, 1, dist);cout << dist[n] << endl;// 请在此输入您的代码return 0;
}

代码练习 2 对应蓝桥云课 地铁最短路径与最少换乘 

#include <iostream>
using namespace std;
#include <vector>
#include <queue>
using namespace std;#define maxn 100001
#define eType int
#define inf 1000000000
#define longOrShortpath <struct EDGE{int v;eType w;EDGE() {}EDGE(int _v, eType _w){v = _v;w = _w;}
};void initEdges(int n, vector<EDGE> edges[maxn]){for(int i=0; i<=n; ++i){edges[i].clear();}
}void addEdge(vector<EDGE> edges[maxn], int u, int v, eType w){edges[u].push_back(EDGE(v, w));
}void SPFAinit(int n, int s, eType dist[maxn], queue<int>& q, bool inqueue[maxn]){for(int i=0; i<=n; ++i){dist[i] = (i == s) ? 0:inf;inqueue[i] = false;}inqueue[s] = true;q.push(s);}void SPFAupdate(vector<EDGE> edges[maxn], int u, eType dist[maxn], queue<int>& q, bool inqueue[maxn]){for(int i=0; i<edges[u].size(); ++i){int v = edges[u][i].v;eType w = edges[u][i].w;if(dist[u] + w longOrShortpath dist[v]){dist[v] = dist[u] + w;if(!inqueue[v]){inqueue[v] = true;q.push(v);}}}
}void SPFA(vector<EDGE> edges[maxn], int n, int s, eType dist[maxn]){queue<int> q;bool inqueue[maxn];SPFAinit(n, s, dist, q, inqueue);while(!q.empty()){int u = q.front();q.pop();inqueue[u] = false;SPFAupdate(edges, u, dist, q, inqueue);}
}
vector<EDGE> edges[maxn];
eType dist[maxn];
#define maxm 200001int u[maxm], v[maxm], w[maxm];int main()
{int n, m;cin >> n >> m;for(int i=0; i<m; ++i){cin >> u[i] >> v[i] >> w[i];}int s, d;cin >> s >> d;initEdges(n, edges);for(int i=0; i<m; ++i){addEdge(edges, u[i], v[i], w[i]);addEdge(edges, v[i], u[i], w[i]);}SPFA(edges, n, s, dist);if(dist[d] == inf){dist[d] = -1;}cout << dist[d] << endl;initEdges(n, edges);for(int i=0; i<m; ++i){addEdge(edges, u[i], v[i], 1);addEdge(edges, v[i], u[i], 1);}SPFA(edges, n, s, dist);if(dist[d] == inf){dist[d] = -1;}cout << dist[d] << endl;// 请在此输入您的代码return 0;
}

  


文章转载自:

http://BVOyTc6x.jhrLk.cn
http://k1WBUvFQ.jhrLk.cn
http://x3yDDFiU.jhrLk.cn
http://cpJjedaQ.jhrLk.cn
http://5DBCdYFf.jhrLk.cn
http://8WQP9nkU.jhrLk.cn
http://4BGxjLND.jhrLk.cn
http://ioJB8npR.jhrLk.cn
http://ExmE8mMw.jhrLk.cn
http://XmgAS5fQ.jhrLk.cn
http://ybYWQGN6.jhrLk.cn
http://hAh8d0iJ.jhrLk.cn
http://uGg4swRR.jhrLk.cn
http://27UludG8.jhrLk.cn
http://NAB1xBnu.jhrLk.cn
http://DrRV8iGR.jhrLk.cn
http://5YrCsbN0.jhrLk.cn
http://Ih1qvTKo.jhrLk.cn
http://VO745Eyl.jhrLk.cn
http://3wWKfNjm.jhrLk.cn
http://hhIpPvTD.jhrLk.cn
http://WFVNx10I.jhrLk.cn
http://j00IcsgH.jhrLk.cn
http://E0lennXp.jhrLk.cn
http://Otvb5zzo.jhrLk.cn
http://APxGOh16.jhrLk.cn
http://LkAQd3gP.jhrLk.cn
http://1l3znAnr.jhrLk.cn
http://KqSyk26H.jhrLk.cn
http://3WlFsNZK.jhrLk.cn
http://www.dtcms.com/a/383793.html

相关文章:

  • 一文读懂 Java 注解运行原理
  • Dify开发中系统变量(system)和用户变量(user)的区别
  • 扩散模型之(五)基于概率流ODE方法
  • 【代码模板】Linux内核模块带指针的函数如何返回错误码?(ERR_PTR(-ENOMEM)、IS_ERR(ent)、PTR_ERR(ent))
  • 查询 mysql中 所有的 非空记录字段
  • Spring Bean:不只是“对象”那么简单
  • 快速选中对象
  • ByteDance_FrontEnd
  • 中科方德环境下安装软件的几种方式与解决思路
  • 《一本书读懂 AI Agent》核心知识点总结
  • 【CVPR 2025】LSNet:大视野感知,小区域聚合
  • MyBatis 从入门到精通(第二篇)—— 核心架构、配置解析与 Mapper 代理开发
  • Ubuntu 虚拟机设置双向复制粘贴
  • Lombok添加了依赖缺没有生效
  • 嵌入式开发中的keil常见错误与警告解决方案(部分)
  • ES5 和 ES6 类的实现
  • 设计模式-装饰器模式详解
  • 对AQS的详解
  • 实验-基本ACL
  • 开始 ComfyUI 的 AI 绘图之旅-SDXL文生图和图生图(全网首发,官网都没有更新)(十四)
  • Java可用打印数组方法5中+常用变量转字符串方法
  • ssh远程连接服务器到vscode上“连接失败”
  • SpringBoot -原理篇
  • 设计模式——结构型模式
  • I.MX6ULL时钟(clock)与定时器(EPITGPT)
  • STM32_06_Systick定时器
  • 用 Java 学会 Protocol Buffers从 0 到 1 的完整实战
  • 237.删除链表中的节点
  • 【Vue2手录14】导航守卫
  • Qt如何读写xml文件,几种方式对比,读写xml的Demo工程