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

创建网站怎么赚钱的网页设计个人简介代码

创建网站怎么赚钱的,网页设计个人简介代码,石家庄微信网站建设,seo搜索C 中最短路算法的详细介绍 最短路算法是图论中的经典问题,旨在找到图中两个节点之间的边权和最小的路径。根据不同的需求和图的特点,有多种算法可以解决这一问题。本文将详细介绍几种常见的单源最短路算法,包括 Dijkstra 算法、Bellman-Ford …

C++ 中最短路算法的详细介绍

最短路算法是图论中的经典问题,旨在找到图中两个节点之间的边权和最小的路径。根据不同的需求和图的特点,有多种算法可以解决这一问题。本文将详细介绍几种常见的单源最短路算法,包括 Dijkstra 算法、Bellman-Ford 算法和 SPFA 算法,并提供相应的 C++ 实现代码。

一、Dijkstra 算法

1. 算法概述

Dijkstra 算法是由荷兰计算机科学家艾兹格·迪科斯彻(Edsger W. Dijkstra)在 1959 年提出的,用于计算单源最短路径。该算法适用于边权非负的有向图或无向图。

2. 算法原理

Dijkstra 算法的核心思想是贪心策略,通过不断选择当前未处理节点中距离起点最近的节点,逐步扩展到所有节点。具体步骤如下:

  1. 初始化:设置起点到自身的距离为 000,其他节点的距离为无穷大(INFINFINF)。
  2. 选择最小距离节点:从未处理的节点中选择距离起点最近的节点 u
  3. 更新邻接节点:遍历节点 u 的所有邻接节点 v,如果通过 uv 的距离比当前记录的距离更短,则更新 v 的距离。
  4. 标记已处理:将节点 u 标记为已处理。
  5. 重复:重复步骤 2-4,直到所有节点都被处理。

3. C++ 实现

以下是 Dijkstra 算法的两种实现方式:朴素版和使用优先队列优化版。

3.1 朴素版 Dijkstra
#include <bits/stdc++.h>
using namespace std;const int N = 1005, INF = 1e9;
int n, m; // 节点数和边数
int d[N]; // 存储起点到各点的最短距离
bool st[N]; // 标记节点是否已处理
vector<pair<int, int>> adj[N]; // 邻接表表示图void dijkstra(int s) {fill(d, d + N, INF);d[s] = 0;for(int i = 1; i <= n; i++) {int u = -1;for(int j = 1; j <= n; j++) {if(!st[j] && (u == -1 || d[j] < d[u])) {u = j;}}if(u == -1) break;st[u] = true;for(auto [v, w] : adj[u]) {if(d[v] > d[u] + w) {d[v] = d[u] + w;}}}
}int main(){cin >> n >> m;for(int i = 0; i < m; i++) {int a, b, c;cin >> a >> b >> c;adj[a].emplace_back(b, c);// 如果是无向图,取消下面的注释// adj[b].emplace_back(a, c);}dijkstra(1); // 假设起点是1for(int i = 1; i <= n; i++) {cout << "从1到" << i << "的最短路为" << d[i] << endl;}return 0;
}
3.2 使用优先队列优化的 Dijkstra

为了优化时间复杂度,可以使用优先队列(堆)来快速选择当前距离起点最近的节点。这样可以将时间复杂度从 O(n2)O(n^2)O(n2) 降低到 O((n+m)log⁡2n)O((n + m)\log_2 n)O((n+m)log2n)

#include <bits/stdc++.h>
using namespace std;const int N = 1005, INF = 1e9;
int n, m; // 节点数和边数
int d[N]; // 存储起点到各点的最短距离
bool st[N]; // 标记节点是否已处理
vector<pair<int, int>> adj[N]; // 邻接表表示图void dijkstra(int s) {fill(d, d + N, INF);d[s] = 0;priority_queue<pair<int, int>, vector<pair<int, int>>, std::greater<pair<int, int>>> pq;pq.emplace(0, s);while(!pq.empty()){auto [dist, u] = pq.top(); pq.pop();if(st[u]) continue;st[u] = true;for(auto [v, w] : adj[u]){if(d[v] > d[u] + w){d[v] = d[u] + w;pq.emplace(d[v], v);}}}
}int main(){cin >> n >> m;for(int i = 0; i < m; i++) {int a, b, c;cin >> a >> b >> c;adj[a].emplace_back(b, c);// 如果是无向图,取消下面的注释// adj[b].emplace_back(a, c);}dijkstra(1); // 假设起点是1for(int i = 1; i <= n; i++) {cout << "从1到" << i << "的最短路为" << d[i] << endl;}return 0;
}

4. 适用场景与注意事项

  • 边权非负:Dijkstra 算法要求所有边的权重为非负数。如果存在负权边,算法可能无法正确工作。
  • 稀疏图与稠密图:对于稀疏图(边数远小于 n2n^2n2),使用优先队列优化的 Dijkstra 效率较高;对于稠密图,可以考虑使用 Floyd-Warshall 算法。
  • 单源最短路径:Dijkstra 算法用于计算单源最短路径,即从一个起点到所有其他节点的最短路径。

二、Bellman-Ford 算法

1. 算法概述

Bellman-Ford 算法由 Robert Floyd 在 1956 年提出,用于计算单源最短路径。与 Dijkstra 算法不同,Bellman-Ford 算法能够处理含有负权边的图,但不适用于含有负权环的图。

2. 算法原理

Bellman-Ford 算法的核心思想是通过对所有边进行多次松弛操作,逐步逼近最短路径。具体步骤如下:

  1. 初始化:设置起点到自身的距离为 000,其他节点的距离为无穷大(INFINFINF)。
  2. 松弛操作:对图中的所有边进行 n−1n-1n1 次松弛操作,其中 nnn 是节点数。每次松弛操作尝试通过当前边缩短起点到终点的距离。
  3. 检测负权环:再进行一次松弛操作,如果仍有距离被更新,说明图中存在负权环。

3. C++ 实现

#include <bits/stdc++.h>
using namespace std;const int N = 1005, INF = 1e9;
int n, m; // 节点数和边数
int d[N]; // 存储起点到各点的最短距离
vector<tuple<int, int, int>> edges; // 存储所有边 (u, v, w)bool bellman_ford(int s) {fill(d, d + N, INF);d[s] = 0;// 进行 n-1 次松弛操作for(int i = 1; i < n; i++) {for(auto [u, v, w] : edges) {if(d[v] > d[u] + w) {d[v] = d[u] + w;}}}// 检测负权环for(auto [u, v, w] : edges) {if(d[v] > d[u] + w) {return false; // 存在负权环}}return true; // 不存在负权环
}int main(){cin >> n >> m;for(int i = 0; i < m; i++) {int a, b, c;cin >> a >> b >> c;edges.emplace_back(a, b, c);}if(bellman_ford(1)) { // 假设起点是1for(int i = 1; i <= n; i++) {cout << "从1到" << i << "的最短路为" << d[i] << endl;}} else {cout << "图中包含负环" << endl;}return 0;
}

4. 适用场景与注意事项

  • 处理负权边:Bellman-Ford 算法能够正确处理含有负权边的图。
  • 检测负权环:如果在 n−1n-1n1 次松弛后,仍能通过某条边缩短距离,说明图中存在负权环。
  • 时间复杂度:Bellman-Ford 算法的时间复杂度为 O(nm)O(nm)O(nm),在边数较多时效率较低。
  • 不适用于含有负权环的图:如果图中存在负权环,算法无法正确计算最短路径。

三、SPFA 算法(队列优化的 Bellman-Ford)

1. 算法概述

SPFA(Shortest Path Faster Algorithm)是一种对 Bellman-Ford 算法的改进,通过使用队列来优化松弛操作的顺序,从而提高算法效率。SPFA 通常比 Bellman-Ford 更快,但在最坏情况下时间复杂度仍为 O(nm)O(nm)O(nm)

2. 算法原理

SPFA 算法的核心思想是动态逼近最短路径,通过队列来维护需要松弛的节点。具体步骤如下:

  1. 初始化:设置起点到自身的距离为 000,其他节点的距离为无穷大(INFINFINF)。将起点加入队列。
  2. 松弛操作:从队列中取出一个节点 u,遍历其所有邻接节点 v,如果通过 uv 的距离比当前记录的距离更短,则更新 v 的距离,并将 v 加入队列(如果 v 不在队列中)。
  3. 重复:重复步骤 2,直到队列为空。
  4. 检测负权环:如果某个节点被松弛的次数超过 n−1n-1n1 次,说明图中存在负权环。

3. C++ 实现

#include <bits/stdc++.h>
using namespace std;const int N = 1005, INF = 1e9;
int n, m; // 节点数和边数
int d[N]; // 存储起点到各点的最短距离
int cnt[N]; // 记录每个节点被松弛的次数
vector<pair<int, int>> adj[N]; // 邻接表表示图
bool in_queue[N]; // 标记节点是否在队列中
queue<int> q; // 队列用于SPFAbool spfa(int s) {fill(d, d + N, INF);d[s] = 0;q.push(s);in_queue[s] = true;cnt[s] = 1;while(!q.empty()){int u = q.front(); q.pop();in_queue[u] = false;for(auto [v, w] : adj[u]){if(d[v] > d[u] + w){d[v] = d[u] + w;if(!in_queue[v]){q.push(v);in_queue[v] = true;cnt[v]++;if(cnt[v] > n) return false; // 存在负权环}}}}return true; // 不存在负权环
}int main(){cin >> n >> m;for(int i = 0; i < m; i++) {int a, b, c;cin >> a >> b >> c;adj[a].emplace_back(b, c);// 如果是无向图,取消下面的注释// adj[b].emplace_back(a, c);}if(spfa(1)) { // 假设起点是1for(int i = 1; i <= n; i++) {cout << "从1到" << i << "的最短路为" << d[i] << endl;}} else {cout << "图中包含负环" << endl;}return 0;
}

4. 适用场景与注意事项

  • 处理负权边:SPFA 算法能够正确处理含有负权边的图。
  • 检测负权环:通过记录每个节点被松弛的次数,可以检测图中是否存在负权环。
  • 平均时间复杂度较低:在一般情况下,SPFA 的平均时间复杂度比 Bellman-Ford 低,但最坏情况下仍为 O(nm)O(nm)O(nm)
  • 不保证最优性:在某些特殊情况下,SPFA 可能无法得到最优解,需要结合具体问题进行分析。

四、Floyd-Warshall 算法(多源最短路)

1. 算法概述

Floyd-Warshall 算法由 Robert Floyd 在 1962 年提出,用于计算图中所有节点对之间的最短路径。该算法适用于含有正权和负权边的有向图或无向图,但不适用于含有负权环的图。

2. 算法原理

Floyd-Warshall 算法基于动态规划的思想,通过枚举中间节点 k,逐步更新所有节点对之间的最短路径。具体步骤如下:

  1. 初始化:创建一个二维数组 d,其中 d[i][j] 表示节点 i 到节点 j 的最短距离。初始时,d[i][j] 为节点 i 到节点 j 的直接边的权重,如果没有直接边,则设为无穷大(INFINFINF)。对角线上的元素 d[i][i] 设为 000
  2. 动态规划:对于每个中间节点 k,遍历所有节点对 (i, j),如果通过 k 可以缩短 ij 的距离,则更新 d[i][j]
  3. 结果:最终,d[i][j] 将包含节点 i 到节点 j 的最短距离。如果 d[i][j] 仍为无穷大,说明 i 无法到达 j

3. C++ 实现

#include <bits/stdc++.h>
using namespace std;const int N = 105, INF = 1e9;
int n, m; // 节点数和边数
int d[N][N]; // 存储最短距离矩阵void floyd(){// 初始化距离矩阵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;}}// 读取边并更新距离矩阵for(int i = 0; i < m; i++) {int a, b, c;cin >> a >> b >> c;d[a][b] = min(d[a][b], c);// 如果是无向图,取消下面的注释// d[b][a] = min(d[b][a], c);}// Floyd-Warshall算法核心部分for(int k = 1; k <= n; k++) {for(int i = 1; i <= n; i++) {for(int j = 1; j <= n; j++) {if(d[i][k] + d[k][j] < d[i][j]) {d[i][j] = d[i][k] + d[k][j];}}}}
}int main(){cin >> n >> m;floyd();// 输出所有节点对的最短距离for(int i = 1; i <= n; i++) {for(int j = 1; j <= n; j++) {if(d[i][j] == INF) cout << "INF ";else cout << d[i][j] << " ";}cout << endl;}return 0;
}

4. 适用场景与注意事项

  • 处理负权边:Floyd-Warshall 算法能够正确处理含有负权边的图。
  • 检测负权环:Floyd-Warshall 算法可以检测图中是否存在负权环。
  • 时间复杂度较高:在密集图中,即边数接近顶点数平方的情况下,Floyd-Warshall算法的效率相对较高。但该算法的时间复杂度为O(n3)O(n^3)O(n3),其中n是图中顶点的数量。因此,在处理大规模图时,可能会遇到性能问题。
  • 空间复杂度较高:算法的空间复杂度为O(n2)O(n^2)O(n2),需要存储一个n×nn\times nn×n的距离矩阵。在内存受限的环境中,这可能成为一个考虑因素。
  • 不适用于含有负权环的图:如果图中存在负权环,Floyd-Warshall 算法无法正确计算最短路径。在这种情况下,可以考虑使用其他算法,如Bellman-Ford算法。

文章转载自:

http://0ynppb2i.jbmbj.cn
http://Yyvdze4U.jbmbj.cn
http://AVOURCoP.jbmbj.cn
http://5boEZq6W.jbmbj.cn
http://hlfWbKSV.jbmbj.cn
http://IAQUP6ZT.jbmbj.cn
http://DUrFIffv.jbmbj.cn
http://qzgdZcEl.jbmbj.cn
http://tR5g6icm.jbmbj.cn
http://WKSwcS0l.jbmbj.cn
http://isK1B8SH.jbmbj.cn
http://AfNjB7tb.jbmbj.cn
http://eVYTVTaX.jbmbj.cn
http://hM6Dsbxk.jbmbj.cn
http://zZZ6tPVq.jbmbj.cn
http://AJRcjB0C.jbmbj.cn
http://rhs4gXYS.jbmbj.cn
http://m5qiLASy.jbmbj.cn
http://JSJBbM8m.jbmbj.cn
http://ve97DHNr.jbmbj.cn
http://cptbwAXa.jbmbj.cn
http://DwLatzRC.jbmbj.cn
http://me1WN1yu.jbmbj.cn
http://IsGMR5Ym.jbmbj.cn
http://cfj4HZYL.jbmbj.cn
http://JfYJsZBq.jbmbj.cn
http://B0gycYJs.jbmbj.cn
http://8SKsbZbC.jbmbj.cn
http://5BI9w3ku.jbmbj.cn
http://d3iNTxzm.jbmbj.cn
http://www.dtcms.com/wzjs/629034.html

相关文章:

  • 网站建设工作流程html阿里云 wordpress 权限
  • 百度统计 wordpress 插件如何做好seo
  • 专业建站开发通州优化公司
  • 如何在网站中做公示信息低价网站备案
  • wordpress 水果主题seo优化网站优化
  • 东阳便宜自适应网站建设优惠网站建设目标计划书
  • 乐山建设企业网站好的wordpress企业模板下载
  • 计算机网站开发要考什么证电脑网页打不开怎么回事
  • 网站建设合同副本红色主题网站模板
  • 官方网站建设方法绍兴网站建设技术外包
  • wordpress一年后续费自己怎么去做seo网站推广?
  • 中小学网站建站模板东莞商业网站建设常识
  • destoon 网站搬迁开发一个小程序要多少钱
  • 金融行业网站建设公司企业网络营销推广方案策划范文
  • 做印量调查的网站营销型网站建设的指导原则不包括
  • 竞价网站建设百度高级搜索怎么用
  • 个人网站模板的优缺点怎么做好网站开发 设计
  • 百度网盘搜索引擎网站中国建筑网官网新闻
  • 深圳蕾奥规划设计公司网站用邮箱地址做网站域名好吗
  • 机构网站源码qq素材网站源码
  • 做 在线观看免费网站万维网如何建设网站
  • python 做的网站有哪些全网关键词搜索工具
  • 甘肃长城建设集团网站罗湖商城网站建设哪家好
  • 湖北营销型网站建设价格品牌营销论文框架
  • 做网站厦门网推公司干什么的
  • 网站开发与维护考察试题如何让网站速度快
  • 网站建设主管招聘弱电工程公司网站怎么做
  • 网站维护一般都是维护什么成都旅游发朋友圈的精美句子
  • 公司怎么建立自己网站南宁住房建设部网站
  • 做网站运营需要注意哪些问题福州网站关键词推广