1、spfa求单源最短路,链式前向星存图, 时间复杂度o(kE) k是常数,大多数情况下为2。

#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;const int N = (int) 1e5 + 11; // 最大点数
const int M = (int) 1e6 + 11; // 最大边数
const int INF = (int) 0x3f3f3f3f;struct Edge{ // 边的定义int to, val, next;Edge(){}Edge(int _to, int _val, int _next){to = _to; val = _val; next = _next;}
}edge[M << 1]; // !!如果是双向图的话,边的数量是题目中描述的二倍int n, m; // n 是图中的点数,m是图中的边数
int head[N], top;
void init(int n){ // 初始化memset(head, -1, sizeof(int) * (n + 1));top = 0;
}
void Add(int u, int v, int val){ // 加单向边edge[top] = Edge(v, val, head[u]);head[u] = top++;
}
void getmap(int m){ // 建图int u, v, val;while(m--){scanf("%d%d%d",&u , &v, &val); // u->v有边Add(u, v, val);  Add(v, u, val); // 如果是双向图,加上这个代码}
}bool vis[N]; int dis[N];
void spfa(int st, int ed){ // 核心代码,点序号从0-(n-1)或者1-n都可以memset(dis, 0x3f, sizeof(int) * (n + 1));memset(vis, false, sizeof(bool) * (n + 1)); // 清空和初始化queue<int>que; que.push(st); vis[st] = true; dis[st] = 0;while(!que.empty()){int u = que.front(); que.pop(); vis[u] = false;for(int i = head[u]; ~i; i = edge[i].next){Edge e = edge[i];if(dis[e.to] > dis[u] + e.val) {//是否可以进行松弛dis[e.to] = dis[u] + e.val;if(!vis[e.to]){ // 是否在队列中,如果在可以跳过que.push(e.to);vis[e.to] = true;}}}} printf("%d\n", dis[ed] == INF ? -1 : dis[ed]); // st到不了ed输出-1
}int main(){int t; scanf("%d%d", &t, &n);init(n);getmap(t);spfa(n, 1);return 0;
}

2、 djk求单源最短路,邻接矩阵存图, 时间复杂度o(n^2)。

#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;const int N = (int) 1000 + 11; // 最大点数
const int INF = (int) 0x3f3f3f3f;int n, m; // n是点的个数,m是边的个数
int mp[N][N];
void init(int n){// 初始化for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){if(i == j) mp[i][j] = 0;else mp[i][j] = mp[j][i] = INF; }}
}
void getmap(int m){ // 建图int u, v, val;while(m--){scanf("%d %d %d", &u, &v, &val);u--; v--;mp[u][v] = mp[v][u] = min(mp[u][v], val); // 如果是双向图写这句  防止输入重边 // mp[u][v] = min(mp[u][v], val); // 如果是单向图写这句}
}
bool vis[N]; int dis[N];
void djk(int st, int ed){ // 核心代码,点的序号是从0-(n-1)for(int i = 0; i < n; i++){vis[i] = false;dis[i] = mp[st][i];} vis[st] = true;for(int i = 1; i < n; i++){int mn = INF, id = -1;  // 找到离起点最近的未访问过得点for(int j = 0; j < n; j++){if(!vis[j] && dis[j] < mn) {mn = dis[j]; id = j;}}if(id == -1) break;vis[id] = true; // 标记for(int j = 0; j < n; j++){if(!vis[j] && mp[id][j] != INF) { // 如果未访问且 id->j有边  if(dis[j] > dis[id] + mp[id][j])  // 是否可以松弛dis[j] = dis[id] + mp[id][j];}}}printf("%d\n", (dis[ed] == INF) ? -1 : dis[ed]);
}
int main(){int t; scanf("%d%d", &t, &n);init(n);getmap(t);djk(n-1, 0);return 0;
}

3、 优先队列优化的djk求单源最短路,链式前向星存图 ,时间复杂度o(E * log(V))。

#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;typedef pair<int, int>pii;
const int N = (int) 1e5 + 11; // 最大点数
const int M = (int) 1e6 + 11;
const int INF = (int) 0x3f3f3f3f;struct Edge{ // 边的定义int to, val, next;Edge(){}Edge(int _to, int _val, int _next){to = _to; val = _val; next = _next;}
}edge[M << 1]; // !!如果是双向图的话,边的数量是题目中描述的二倍int n, m;   // n 是图中的点数,m是图中的边数
int head[N], top;
void init(int n){ // 初始化memset(head, -1, sizeof(int) * (n + 1));top = 0;
}
void Add(int u, int v, int val){     // 加单向边edge[top] = Edge(v, val, head[u]);head[u] = top++;
}
void getmap(int m){ // 建图int u, v, val;while(m--){scanf("%d %d %d",&u , &v, &val); // u->v有边Add(u, v, val);  Add(v, u, val); // 如果是双向图,加上这个代码}
}
int dis[N];
void djk(int st, int ed){ // 核心代码,点的序号可以从0-(n-1)或者1-nmemset(dis, 0x3f, sizeof(int) * (n + 1));priority_queue<pii, vector<pii>, greater<pii> > que; dis[st] = 0; que.push(make_pair(0, st));  // make_pair(dis, v) 表示v到起点的距离为diswhile(!que.empty()){pii p = que.top(); que.pop(); // 每次取离起点最近的int v = p.second;if(dis[v] < p.first) continue; // 如果 没有更优,跳过for(int i = head[v]; ~i; i = edge[i].next){Edge e = edge[i];if(dis[e.to] > dis[v] + e.val) { // 是否可以进行松弛dis[e.to] = dis[v] + e.val;que.push(make_pair(dis[e.to], e.to));}}}printf("%d\n", dis[ed] == INF ? -1 : dis[ed]);
}
int main(){int t; scanf("%d%d", &t, &n);init(n);getmap(t);djk(n, 1);return 0;
}

4、floyd求多源最短路,邻接矩阵存图 时间复杂度o(n^3),可求得任意两个点之间的最短距离。

#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;const int N = (int) 1000 + 11;
const int INF = (int) 0x3f3f3f3f;int n, m;
int mp[N][N];
void init(int n){ // 初始化for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){if(i == j) mp[i][j] = 0;else mp[i][j] = mp[j][i] = INF;}}
}
void getmap(int m){ // 建图int u, v, val;while(m--){scanf("%d%d%d", &u, &v, &val); u--; v--;mp[u][v] = mp[v][u] = min(mp[u][v], val); // 双向图写这行//mp[u][v] = min(mp[u][v], val); // 单向图写这行}
}
void floyd(int n){ // 核心代码,点的序号为0-n-1for(int k = 0; k < n; k++){ for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]); // dp}}}
}int main(){int t; scanf("%d%d", &t, &n);init(n);getmap(t);floyd(n);printf("%d\n", mp[n - 1][0] == INF ? -1 : mp[n - 1][0]);return 0;
}

求解最短路问题的几种方法总结相关推荐

  1. MATLAB求解线性方程组的八种方法

    MATLAB求解线性方程组的八种方法 求解线性方程分为两种方法–直接法和迭代法 常见的方法一共有8种 直接法 Gauss消去法 Cholesky分解法 迭代法 Jacobi迭代法 Gauss-Seid ...

  2. python线性方程组求解_python求解方程组的三种方法

    python求解方程组的三种方法: Numpy求解方程组x + 2y = 3 4x + 5y = 6 当然我们可以手动写出解析解,然后写一个函数来求解,这实际上只是用 Python 来单纯做" ...

  3. 第二十二章:求解素数的N种方法

    求解素数的N种方法 一.质数和合数 质数: 质数又称**素数**.指在一个大于 1的自然数中,除了 1和此整数自身外,不能被其他自然数整除的数.换句话说,只有两个正因数(1和自己)的自然数即为质数. ...

  4. hive求解中位数的几种方法

    hive求解中位数的几种方法 前言 两种解法 解法1:利用中位数的位次特征 解法2:利用升序与降序的差值 解法2.1: 延伸问题:频次+分数 参考文章 前言 假设我们有一张学生成绩表student_s ...

  5. 算法导论中求解时间复杂度的三种方法

    这一章讲的是递归式(recurrence),递归式是一组等式或不等式,它所描述的函数是用在更小的输入下该函数的值来定义的. 本章讲了三种方法来解递归式,分别是代换法,递归树方法,主方法. 1.代换法( ...

  6. Excel规划求解Solver:三种方法的区别

    Excel Solver作为常用的最优解解决工具,在选择解决方法(solving method)的时候有三种选项,这三种选项有什么区别?什么时候该选择哪种方法?在本文做综合解释 目录 1. GRG N ...

  7. Matlab求解线性方程组的三种方法(wzl)

    A=[3 12 1;12 0 2;0 2 3]; b=[2.36;5.26;2.77]; %第一种方法 A\b %当无穷多解时,会使得解中尽量多0 %可算无解方程组%第二种方法 pinv(A)*b % ...

  8. matlab方程近似求根,matlab求解方程的几种方法

    k=i-1; xk=x(i);[(i-1) xk yk piancha xdpiancha] return ; end end if i>gxmax disp('请注意:迭代次数超过给定的最大值 ...

  9. MATLAB求解非线性方程组的五种方法

    MATLAB求解非线性方程组的五种方法 求解线性方程分为两种方法–二分法和迭代法 常见的方法一共有5种 二分法 迭代法 牛顿法 割线法 拟牛顿法 Halley法 使用条件 二分法需要知道两个自变量,分 ...

最新文章

  1. java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 \ ^
  2. PHP----------线程安全和非线程安全的介绍
  3. 数据中心柴油发电机系统的使用和维护
  4. Executors.newFixedThreadPool和ArrayBlockingQueue一点使用心得
  5. Visual Studio 2017 15.9 版本发布:推出全新的导入 / 导出配置功能
  6. yii2通过url访问类中的方法_每日学点---nginx变量使用方法详解(3)
  7. CloudEngine 6800 堆叠场景下配置eth-trunk链路聚合流量负载不均衡
  8. 扩展中断控制器8259实验_PCIe的中断机制
  9. ERROR Utils: Uncaught exception in thread stdout writer for python
  10. 解决办法:RuntimeError: dictionary changed size during iteration
  11. 【设计模式】03-抽象工厂模式
  12. 【 C# 】ListView控件的基本属性和常用方法详解
  13. 微信小程序中的列表渲染
  14. Win7 vs2010+Silverlight4开发安装顺序
  15. 【C语言】案例四十九 学生档案管理系统
  16. 立而不破,华为云注解政企智能升级的“道与术”
  17. FPGA自学笔记--串口通信发送多字节数据(verilog版)
  18. 共享单车创始人正在沦为资本家的傀儡?
  19. 2.给出距离1900年1月1日的天数,求日期
  20. 【AD620/OP07】高压电流采样电路设计方案

热门文章

  1. 【评价指标】AUC和accuracy有什么内在关系?
  2. 玉林师范学院计算机宿舍专业,玉林师范学院宿舍条件,宿舍环境图片(10篇)
  3. SQL语句case函数
  4. 《光明传说》主城建筑图文详解の光之塔
  5. 笔记本CPU利用率卡在16%不动弹的一点解决心得
  6. Spring使用静态工厂和实例化工厂创建对象
  7. cannel mysql_mysql、canal、kafka、数据同步系列(四)canal的安装和配置
  8. 通过爬取美剧天堂详细介绍Scrapy 框架入门
  9. js正则贪婪模式_JS关于正则的非贪婪模式
  10. SQL server数据库语句自定义排序