迪杰斯特拉算法百度百科定义:传送门

gh大佬博客:传送门

迪杰斯特拉算法用来计算一个点到其他所有点的最短路径,是一种时间复杂度相对比较优秀的算法 O(n2)(相对于Floyd算法来说)

是一种单源最短路径算法,但是它并不能处理负边权的情况

Dijkstra的算法思想:①将一开始所有的非源点到源的距离设置成无限大(你认为的无限大实际上是0x3f(int)或者0x7fffffff(long long)),然后源到源距离设置成0(不就是0吗),然后每次找到一个距离源最短的点u,将其变成白点,枚举所有的蓝点,如果源到白点存在中转站——一个蓝点使得源->蓝点和蓝点->白点的距离和更短,就更新。②每找到一个白点,就尝试更新其他蓝点,直到更新完毕。

代码及注释:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<time.h>
#include<queue>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define fi first
#define sc second
ld eps=1e-9;
ll pp=1000000007;
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll read(){ll ans=0;char last=' ',ch=getchar();while(ch<'0' || ch>'9')last=ch,ch=getchar();while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();if(last=='-')ans=-ans;return ans;
}//快读
//headconst int maxn=5001;
int g[maxn][maxn];//g数组用来存储图;
int n,m,s;//分别表示点的个数、有向边的个数、出发点的编号;
bool vis[maxn];//表示是否已经到达过;
int d[maxn];//d[i]表示从询问点到点i的最短路径;
const int inf=2147483647;int main ()
{n=read(),m=read(),s=read();rep(i,1,n){d[i]=inf;rep(j,1,n)g[i][j]=inf;g[i][i]=0;//自己到自己的最短路径当然是0 }//初始化数组;
    rep(i,1,m){int u=read(),v=read(),w=read();//u,v,i分别表示第i条有向边的出发点、目标点和长度;g[u][v]=w;//读入;
    }vis[s]=1;//将起点标记成已经到达;
    rep(i,1,n)d[i]=g[s][i];//将最短路径初始化;//如果两点之间有路线就初始化为该距离,如果没有就还是inf;while(1){int stt_node=0,stt_dis=inf;//stt=shortest 初始化两个变量 // stt_node表示最短路径的终点,stt_dis表示最短路径的长度
        rep(i,1,n){ if(vis[i]==0&&d[i]<stt_dis)//如果该点还没有到达,并且他的距离小于最短距离
            {stt_node=i,stt_dis=d[i];//更新变量
            }}if(stt_node==0) break;//如果已经没有可以更新的最短路径了,就说明已经结束了
        vis[stt_node]=1;//将该点标记成已经到达
        rep(i,1,n){if(vis[i]||g[stt_node][i]==inf)continue;//如果并没有到达或者是两点之间没有路径,就进入下一层循环
            d[i]=min(d[i],stt_dis+g[stt_node][i]);//更新最短路径
        }}rep(i,1,n)printf("%d ",d[i]);return 0;
}

我们考虑一下对它的优化。因为如果我们每一次都要扫一遍判断出边,我们还不如直接存出边:

邻接表!(链式前向星)

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<time.h>
#include<queue>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define fi first
#define sc second
ld eps=1e-9;
ll pp=1000000007;
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll read(){ll ans=0;char last=' ',ch=getchar();while(ch<'0' || ch>'9')last=ch,ch=getchar();while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();if(last=='-')ans=-ans;return ans;
}//快读
//headconst ll INF = 2147483647;
struct edge
{ll to, dis_, next;
} Edge[9999999];
struct node
{ll to, dis;inline friend bool operator<(const node &a, const node &b){return a.dis < b.dis;}
};
ll head[9999999], dis[9999999];
bool vst[9999999];
ll nodenum, edgenum, origin_node, cnt = 1, t;
priority_queue<node> q;inline void add_edge(ll from, ll to, ll value)
{Edge[cnt].to = to;Edge[cnt].dis_ = value;Edge[cnt].next = head[from];head[from] = cnt++;
}inline void dijkstra()
{for (register int i = 1; i < origin_node; i++){dis[i] = INF;}//dis[origin_node]=0;for (register int i = origin_node + 1; i <= nodenum; i++){dis[i] = INF;}q.push((node){origin_node, 0});while (!q.empty()){int x = q.top().to;q.pop();if (vst[x])continue;vst[x] = 1;for (register int i = head[x]; i; i = Edge[i].next){dis[Edge[i].to] = min(dis[Edge[i].to], dis[x] + Edge[i].dis_);q.push((node){Edge[i].to, dis[Edge[i].to]});}}
}int main()
{nodenum = read(), edgenum = read(), origin_node = read() ;//t=read();for (register int i = 1; i <= edgenum; i++){register int f, t, v;f = read(), t = read(), v = read();add_edge(f, t, v);}dijkstra();rep(i,1,nodenum){printf("%lld ",dis[i]);}return 0;
}

转载于:https://www.cnblogs.com/lcezych/p/10739866.html

Dijkstra算法——计算一个点到其他所有点的最短路径的算法相关推荐

  1. python计算坐标点欧式距离_Python计算一个点到所有点的欧式距离实现方法

    Python计算一个点到所有点的欧式距离实现方法 如下所示: distances = np.sqrt(np.sum(np.asarray(airportPosition - x_vals)**2, a ...

  2. Bellman_Ford算法(求一个点到任意一点的最短距离)

    单源最短路问题是固定一个起点,求它到任意一点最短路的问题. 记从起点出发到顶点 i 的最短距离为d[i],则有以下等式成立 d[i]=min{d[j]+(从j到 i 的边的权值) 看代码 #inclu ...

  3. Python中计算两个数据点之间的欧式距离,一个点到数据集中其他点的距离之和

    计算数两个数据点之间的欧式距离 import numpy as np def ed(m, n):return np.sqrt(np.sum((m - n) ** 2)) i = np.array([1 ...

  4. 关于 高斯算法计算某数可以被分割成连续自然数之和的组数 个人的一点拙见

    题目描述:基于高斯算法计算一个正整数可以被分割成多少组连续(包括自身)的自然数之和? 如: 3=3: 3=1+2: 5=5: 5=2+3: 6=6: 6=1+2+3: ....... 解题思路: 由S ...

  5. 求解两点间最短路径的算法

    最短路径算法 1.Dijkstra算法 2.Bellman-Ford算法 3.SPFA算法 4.Floyd算法 几种最短路径算法的对比 Dijkstra算法.Bellman-Ford算法和SPFA算法 ...

  6. python贪心算法最短路径_dijkstra算法(贪心算法)——解决最短路径问题

    最短路径 给定一张带权图和其中的一个点(作为源点),求源点到其余顶点的最短路径 基本思想 1)源点u,所有顶点的集合V,集合S(S中存有的顶点,他们到源点的最短路径已经确定,源点u默认在S中),集合V ...

  7. 最短路径flody算法

    1.定义概览 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的 ...

  8. Java数据结构与算法(九)-程序员常用的10中算法

    本章目录 第14章 程序员常用的10中算法 14.1 二分查找算法(非递归) 14.1.1 二分查找算法(非递归)介绍 14.2 分治算法 14.2.1 分治算法介绍 14.2.2 分治算法最佳实践- ...

  9. 国科大计算机算法设计与分析陈玉福,中科院陈玉福计算机算法设计与分析期末简答题答案.pdf...

    中科院陈玉福计算机算法设计与分析期末简答题答案 1. 贪心算法和动态规划算法有什么共同点和区别?它们都有那些优势和劣势? 共通点:动态规划和贪心算法都是一种递推算法 ,均有局部最优解来推导全局最优解 ...

最新文章

  1. 2021牛客暑期多校训练营3 I-Kuriyama Mirai and Exclusive Or (差分+位运算)
  2. 在Python中计算一次性计算多个百分位数percentile、quantile
  3. 软考培训 - 2014年3月1日信息系统项目管理师开班
  4. 《程序员》2007第2期,新产品工具点评 特别推荐“万能数据库查询分析器”发布...
  5. java自定义注解解析及自定义注解
  6. Netty学习笔记(三)EventLoopGroup开篇
  7. preprocessor预处理器
  8. 向mysql中添加更新时间_mysql 实现添加时间自动添加更新时间自动更新操作
  9. k8s核心技术-Pod(调度策略)_创建Pod流程_比如一个nginx的Pod创建后如何被分配到某个节点上---K8S_Google工作笔记0024
  10. python可以神奇的做什么_可以用 Python 编程语言做哪些神奇好玩的事情?
  11. This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
  12. 数学画图软件_关于数学建模(或科研绘图)的画图学习建议
  13. PDF证书加密文件如何解密?
  14. QGIS免费获取并加载行政区边界
  15. [024] 欢迎大家关注我的微信公众帐号小q机器人(xiaoqrobot)
  16. 好玩的猜数游戏(不是二分查找!四位数)
  17. PV、UV、IP理解
  18. Docker教程(一):docker安装及运行原理
  19. 精力管理--分享感悟
  20. Neo4j 第一篇:在Windows环境中安装Neo4j

热门文章

  1. Linux命令gitview,使用linux的gitview命令查看文件内容
  2. django settings 定义的变量不存在_使用Django部署机器学习模型(1)
  3. win10禁用驱动程序强制签名_图文细说 win10系统未检测到第三个监视器的途径 -win10使用教程...
  4. 多个cpp文件生成so_C++:C++的文件搜索路径
  5. 怎样自动提取邮件的内容_这些最新的外贸搜索开发工具(图灵搜、谷歌搜索提取工具、易查查),你会使用吗?...
  6. C++STL Vector
  7. java用户名检查数据库_登入界面账号密码是访问数据库,但登入问题时if判断时就是执行不了...
  8. java 插入mysql 日期_Java日期-插入数据库
  9. php 链接文件名_7、php-fpm进程管理
  10. python做股票分析_利用Python进行股票投资组合分析(调试)