学校网站的建设目标wordpress淘宝客跳转
news/
2025/9/23 9:50:37/
文章来源:
学校网站的建设目标,wordpress淘宝客跳转,仿照别的网站做,济南 制作网站 公司哪家好解决图论问题中的最短路径问题一般有四种算法#xff0c;分别是Floyd算法、Dijkstra算法、Bellman-Ford算法和SPFA算法#xff0c;下面介绍一下这几种算法的模板和原理用途。
Floyd算法
原理#xff1a;Floyd本质上是一个动态规划的思想#xff0c;每一次循环更新经过前k… 解决图论问题中的最短路径问题一般有四种算法分别是Floyd算法、Dijkstra算法、Bellman-Ford算法和SPFA算法下面介绍一下这几种算法的模板和原理用途。
Floyd算法
原理Floyd本质上是一个动态规划的思想每一次循环更新经过前k个节点i到j的最短路径。
用途Floyd算法是求解多源最短路时通常选用的算法经过一次算法即可求出任意两点之间的最短距离并且可以处理有负权边的情况但无法处理负权环。时间复杂度为O(n3)。
代码框架
#define N 100
const int INF 0x3f3f3f3f;
int d[N][N];
// 代码初始化,共有n个顶点
for(int i 0; i n; i){for(int j 0; j n; j){d[i][j] i j ? 0 : INF;}
}
// 将每条边的值加入到dis中去这里不再赘叙
// Floyd算法
for(int k 0; k n; k){for(int i 0; i n; i){for(int j 0; j n; j){d[i][j] min(d[i][j], d[i][k] d[k][j]);}}
}
Dijkstra算法
原理将结点分成两个集合已确定最短路长度的点集记为S集合的和未确定最短路长度的点集记为T集合。一开始所有的点都属于T集合。
初始化dis(S) 0其他点的S均为INT_MAX。
然后重复这些操作 从T集合中选取一个最短路长度最小的结点移到S集合中。 对那些刚刚被加入S集合的结点p的所有出边执行松弛操作。松弛操作即更新dis(T)的值具体公式为dis(T) min(dis(T), dis(p) w(p)(T))。
直到T集合为空算法结束。
用途基于贪心思想的一种求解 非负权图 上单源最短路径的算法。暴力的话O(n * n)。
代码框架
// 假设共有n个节点
#define N 100
vectorvectorint w; // 储存每条边的权重
int dis[N]; // 储存开始节点到其他节点的最短距离
bool s[N]; // 储存已找到最短路径的节点
int dijkstra(int x, int des){ // 假设x节点为开始节点,des目的节点// 初始化dismemset(dis, 0x3f, sizeof(dis));dis[x] 0;for(int i 0; i n; i){int p -1; // 本次循环加入到S集合的节点for(int j 0; j n; j){ // 在集合T中寻找距离最小的节点if(!s[j] (p -1 || dis[p] dis[j])){t j;}}//用p更新其他节点到开始节点x的最短距离for(int j 0; j n; j){dis[j] minx(dis[j], dis[p] w[p][j]);}s[p] true;}return dis[des];
}
Bellman-Ford算法
原理逐基于动态规划遍的对图中每一个边去迭代计算起始点到其余各点的最短路径松弛操作执行n - 1遍最终得到起始点到其余各点的最短路径。
用途Bellman–Ford 算法是一种基于松弛relax操作的单源最短路算法可以处理负权边与负权回路。对于一个不包含负权环的V个点的图任意两点之间的最短路径至多包含V-1条边。如果存在负权环每次在负权环上走一圈都会使环上的每一个点的距离减少因此不存在最短路径。时间复杂度为O(nm)其中n为节点个数m为边数。
可以解决边数限制的最短路径问题SPFA无法代替。
代码框架
// 假设共有n个节点m条边
struct Edge { // 边u表示出点v表示入点w表示边的权重 int u, v, w;
}edges[m];
int dis[100]; // 储存开始节点到其他节点的最短距离
int Bellman_Ford(int start, int des){ // 开始节点为start结束节点为desmemset(dis, 0x3f, sizeof(dis));dis[start] 0;for(int i 0; i n; i){ // 迭代n 次for(int j 0; j m; j){if(i n - 1 dis[edges[i].v] dis[edges[i].u] edges[i].w){// 判断是否出现负权回路// 最短距离发生更新说明存在负权回路返回-1return -1;}dis[edges[j].v] min(dis[edges[j].v], dis[edges[j].u] edges[j].w);}}return dis[des] 0x3f3f3f3f / 2 ? -1 : dis[des];
}
SPFA算法
原理初始时将起点加入队列。每次从队列中取出一个元素并对所有与它相邻的点进行修改若某个相邻的点修改成功则将其入队。直到队列为空时算法结束。算法的流程为 将除源点之外的所有的点当前距离初始化为无穷并标记为未入队。源点的当前距离为0将源点入队。 取出队首u遍历u的所有出边检查是否能更新所连接的点v的当前距离。如果v的当前距离被更新并且v不在队中则将v入队。重复该操作直到队列为空。 检查是否存在负权环的方法为记录一个点的入队次数如果超过n-1次说明存在负权环因为最短路径上除自身外至多n-1个点故一个点不可能被更新超过n-1次。
用途SPFA是队列优化的Bellman-Ford算法因此用途与Bellman-Ford算法用途相同但是时间复杂度更低。平均复杂度O(m)最坏复杂度O(n * m)。
代码框架
// 假设共有n个节点m条边
#define N 100
struct Edge { // v表示出边w表示边的权重 int v, w;
};
vectorEdge e[n]; // 与各个节点相连的边
int dis[N]; // 储存开始节点到其他节点的最短距离
bool s[N]; // 判断节点是否在队列中
int cnt[N]; // 记录边数
int spfa(int start, int des){ // 开始节点为start结束节点为desmemset(dis, 0x3f, sizeof(dis));dis[start] 0;queueint q;q.push(start);s[start] true;while(!q.empty()){int u q.front();q.pop();s[u] false;for(auto ed : e[u]){ // 遍历节点p能直接到达的节点,松弛操作int v ed.v, w ed.w;if(dis[v] dis[u] w){dis[v] dis[u] w;cnt[v] cnt[u] 1;if(cnt[v] n){ // 出现负权回路return -1;}if(!s[v]){q.push(v);s[v] true;}}}}return dis[des] 0x3f3f3f3f / 2 ? -1 : dis[des];
}
总结
1单源最短路给定V中的一个顶点称为源。要计算从源到其他所有各顶点的最短路径长度。这里的长度就是指路上各边权之和。这个问题通常称为单源最短路径 问题。
所有边权都是正数
朴素Dijkstra算法 O(n^2) 适合稠密图贪心思想
堆优化版的Dijkstra算法 O(mlogn)适合稀疏图贪心思想
存在负权边
Bellman-ford O(nm)动态规划思想
SPFA 一般O(m)最坏O(nm)
2多源汇最短路任意两点最短路径被称为多源最短路径即给定任意两个点一个出发点一个到达点求这两个点的之间的最短路径就是任意两点最短路径问题Floyd算法 O(n^3)
题单
743. 网络延迟时间 - 力扣LeetCode
787. K 站中转内最便宜的航班 - 力扣LeetCode
1928. 规定时间内到达终点的最小花费 - 力扣LeetCode
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912107.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!