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

最短路算法

最短路

在这里插入图片描述

单源最短路

朴素dijkstra

时间复杂度O(n^2),适用于稠密图,所以用邻接矩阵存储

#include<cstring>
#include<iostream>
#include<algorithm>using namespace std;const int N=510;int n,m;
int g[N][N];
int dist[N];
bool st[N];int dijkstra(){memset(dist,0x3f,sizeof(dist));dist[1] = 0;for(int i=0;i<n;i++){int t=-1;for(int j=1;j<=n;j++){if(!st[j] && (t==-1||dist[t]>dist[j]))t = j;}st[t]=true;for (int j = 1;j<=n;j++)dist[j] = min(dist[j], dist[t] + g[t][j]);}if(dist[n]==0x3f3f3f) return -1;return dist[n];
}int main(){scanf("%d%d",&n,&m);memset(g,0x3f,sizeof(g));while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);g[a][b] = min(g[a][b], c);}int t=dijkstra();printf("%d\n", t);
}

堆优化dijkstra

时间复杂度m*logn

#include<bits/stdc++.h>
using namespace std;const int N = 100010;
typedef pair<int, int> PII;int n, m;
vector<PII> edge[N];
int dist[N];
bool st[N];int dijkstra()
{memset(dist, 0x3f, sizeof(dist));dist[1] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});while (heap.size()){auto t = heap.top();heap.pop();int ver = t.second;if (st[ver])continue;st[ver] = true;for (auto k : edge[ver]){int to = k.first;int w = k.second;if (dist[to] > dist[ver] + w){dist[to] = dist[ver] + w;heap.push({dist[to], to});}}}if (dist[n] == 0x3f3f3f3f)return -1;return dist[n];
}int main()
{scanf("%d%d", &n, &m);while (m--){int a, b, c;scanf("%d%d%d", &a, &b, &c);edge[a].push_back({b, c});}int t = dijkstra();printf("%d\n", t);
}
/*
3 3
1 2 2
2 3 1
1 3 4
输出
3*/

朴素bellman_ford

时间复杂度:O(nm)

k是经过多少条边,该算法可以求一点点经过多少条边到另外一点的最短路径

求1到n的最短路径,k为n-1

#include<bits/stdc++.h>using namespace std;
const int N = 510, M = 10010;int n,m,k;
int dist[N],backup[N];struct Edge{int a, b, w;
}edges[M];int bellman_ford(){memset(dist, 0x3f, sizeof(dist));dist[1] = 0;for(int i=0;i<k;i++){memcpy(backup,dist,sizeof(dist));for (int j = 0;j<m;j++){int a = edges[j].a, b = edges[j].b, w = edges[j].w;dist[b] = min(dist[b], backup[a] + w);}}if(dist[n]>0x3f3f3f3f/2)  return -1;  //防止∞+(-10) 更新∞return dist[n];
}int main(){scanf("%d%d%d",&n,&m,&k);for (int i = 0; i < m;i++){int a,b,w;scanf("%d%d%d", &a, &b, &w);edges[i] = {a, b, w};}int t=bellman_ford();printf("%d", t);
}
/*
3 3 1
1 2 1
2 3 1
1 3 3
输出
3
*/

优化spfa

限制:图中有负环

时间复杂度一般O(m),最坏O(nm)

#include<bits/stdc++.h>
using namespace std;const int N = 100010;
typedef pair<int, int> PII;int n, m;
vector<PII> edge[N];
int dist[N];
bool st[N];int spfa()
{memset(dist, 0x3f, sizeof(dist));dist[1] = 0;queue<int> q;q.push(1);st[1]=true;while(q.size()){int t=q.front();q.pop();st[t]=false;for (auto k:edge[t]){int to=k.first,w=k.second;if(dist[to] > dist[t] + w){dist[to] = dist[t] + w;if(!st[to]){q.push(to);st[to] = true;}}}}if (dist[n] == 0x3f3f3f3f)return -1;return dist[n];
}int main()
{scanf("%d%d", &n, &m);while (m--){int a, b, c;scanf("%d%d%d", &a, &b, &c);edge[a].push_back({b, c});}int t = spfa();printf("%d\n", t);
}
/*
3 3
1 2 2
2 3 1
1 3 4
输出
3*/

spfa检测负环

#include<bits/stdc++.h>
using namespace std;const int N = 100010;
typedef pair<int, int> PII;int n, m;
vector<PII> edge[N];
int dist[N],cnt[N];
bool st[N];int spfa()
{queue<int> q;for (int i = 1;i<=n;i++){st[i]=true;q.push(i);}while (q.size()){int t = q.front();q.pop();st[t] = false;for (auto k : edge[t]){int to = k.first, w = k.second;if (dist[to] > dist[t] + w){dist[to] = dist[t] + w;cnt[to] = cnt[t] + 1;if(cnt[to] >= n)  return true;if (!st[to]){q.push(to);st[to] = true;}}}}return false;
}int main()
{scanf("%d%d", &n, &m);while (m--){int a, b, c;scanf("%d%d%d", &a, &b, &c);edge[a].push_back({b, c});}if(spfa()) puts("yes");else puts("no");
}
/*
3 3
1 2 -1
2 3 4
3 1 -4
输出
yes*/

多源最短路

Floyd

#include<bits/stdc++.h>using namespace std;const int N = 210, INF = 1e9;int n,m,Q;
int d[N][N];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(){scanf("%d%d%d",&n,&m,&Q);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,w;scanf("%d%d%d",&a,&b,&w);d[a][b] = min(d[a][b], w);//重边}floyd();while(Q--){int a,b;scanf("%d%d",&a,&b);if(d[a][b]>INF/2) puts("impossible");else printf("%d\n", d[a][b]);}return 0;
}
/*
3 3 2
1 2 1
2 3 2
1 3 1
2 1
1 3
输出
impossible
1*/
http://www.xdnf.cn/news/16239.html

相关文章:

  • 美林数据用大模型重构电能质量评估,让隐蔽合规问题无所遁形
  • es 和 lucene 的区别
  • 比例谐振控制器(PR控制器)在交流系统中的应用原理详细解析
  • 【OpenCV篇】OpenCV——03day.图像预处理(2)
  • AI大模型各类概念扫盲
  • 汽车需求管理的关键要素及适合汽车行业的最佳需求管理解决方案Jama Connect
  • 《设计模式之禅》笔记摘录 - 9.责任链模式
  • 4️⃣字典(dict)速查表
  • 阶段1--域名服务器
  • Java开发岗面试记录合集
  • 一二章笔记总结
  • Ubuntu系统下FFmpeg源码编译安装
  • 【Pytorch】数据集的加载和处理(二)
  • 纯CPU场景下C++的分布式模型训练框架设计思路
  • 刷完jetpack后无法打开安装的浏览器的解决办法useful
  • Linux dd命令 数据备份、转换与磁盘操作的终极工具
  • 分布式任务调度实战:XXL-JOB与Elastic-Job深度解析
  • OpenLayers 快速入门(六)Interaction 对象
  • 模拟实现消息队列项目
  • 7月23日星期三今日早报简报微语报早读
  • C基础 07_综合案例《猜拳游戏》
  • Android NDK与JNI深度解析
  • HarmonyOS Flutter Boost完全接入手册:爬完所有坑的实战指南
  • 双写缓冲区 Redo Log
  • C++缺省参数
  • React项目运行环境与执行顺序及动态路由等使用注意点
  • 数据结构系列之AVL树
  • 1、黑马点评复盘(短信登录-Session或Redis实现)
  • 不同地区的主要搜索引擎工具
  • 嵌入式linux下的NES游戏显示效果优化方案:infoNES显示效果优化