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

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(-);
#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-;
ll pp=;
ll mo(ll a,ll pp){if(a>= && a<pp)return a;a%=pp;if(a<)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=;for(;b;b>>=,a=mo(a*a,pp))if(b&)ans=mo(ans*a,pp);return ans;}
ll read(){
ll ans=;
char last=' ',ch=getchar();
while(ch<'' || ch>'')last=ch,ch=getchar();
while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
if(last=='-')ans=-ans;
return ans;
}//快读
//head const int maxn=;
int g[maxn][maxn];//g数组用来存储图;
int n,m,s;//分别表示点的个数、有向边的个数、出发点的编号;
bool vis[maxn];//表示是否已经到达过;
int d[maxn];//d[i]表示从询问点到点i的最短路径;
const int inf=; int main ()
{
n=read(),m=read(),s=read();
rep(i,,n)
{
d[i]=inf; rep(j,,n)
g[i][j]=inf; g[i][i]=;//自己到自己的最短路径当然是0
}//初始化数组; rep(i,,m)
{
int u=read(),v=read(),w=read();
//u,v,i分别表示第i条有向边的出发点、目标点和长度;
g[u][v]=w;//读入;
} vis[s]=;//将起点标记成已经到达; rep(i,,n)
d[i]=g[s][i];//将最短路径初始化;
//如果两点之间有路线就初始化为该距离,如果没有就还是inf; while()
{
int stt_node=,stt_dis=inf;//stt=shortest 初始化两个变量
// stt_node表示最短路径的终点,stt_dis表示最短路径的长度 rep(i,,n)
{
if(vis[i]==&&d[i]<stt_dis)
//如果该点还没有到达,并且他的距离小于最短距离
{
stt_node=i,stt_dis=d[i];//更新变量
}
} if(stt_node==) break;
//如果已经没有可以更新的最短路径了,就说明已经结束了 vis[stt_node]=;//将该点标记成已经到达 rep(i,,n)
{
if(vis[i]||g[stt_node][i]==inf)continue;
//如果并没有到达或者是两点之间没有路径,就进入下一层循环 d[i]=min(d[i],stt_dis+g[stt_node][i]);//更新最短路径
}
} rep(i,,n)
printf("%d ",d[i]);
return ;
}

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

邻接表!(链式前向星)

#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(-);
#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-;
ll pp=;
ll mo(ll a,ll pp){if(a>= && a<pp)return a;a%=pp;if(a<)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=;for(;b;b>>=,a=mo(a*a,pp))if(b&)ans=mo(ans*a,pp);return ans;}
ll read(){
ll ans=;
char last=' ',ch=getchar();
while(ch<'' || ch>'')last=ch,ch=getchar();
while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
if(last=='-')ans=-ans;
return ans;
}//快读
//head const ll INF = ;
struct edge
{
ll to, dis_, next;
} Edge[];
struct node
{
ll to, dis;
inline friend bool operator<(const node &a, const node &b)
{
return a.dis < b.dis;
}
};
ll head[], dis[];
bool vst[];
ll nodenum, edgenum, origin_node, cnt = , 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 = ; i < origin_node; i++)
{
dis[i] = INF;
}
//dis[origin_node]=0;
for (register int i = origin_node + ; i <= nodenum; i++)
{
dis[i] = INF;
}
q.push((node){origin_node, });
while (!q.empty())
{
int x = q.top().to;
q.pop();
if (vst[x])
continue;
vst[x] = ;
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 = ; i <= edgenum; i++)
{
register int f, t, v;
f = read(), t = read(), v = read();
add_edge(f, t, v);
}
dijkstra();
rep(i,,nodenum)
{
printf("%lld ",dis[i]);
} return ;
}

Dijkstra算法——计算一个点到其他所有点的最短路径的算法的更多相关文章

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

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

  2. 最短路径Floyd算法【图文详解】

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

  3. Dijkstra 算法——计算有权最短路径(边有权值)

    [0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在理解 Dijkstra 的思想并用源代码加以实现: 0.2)最短路径算法的基础知识,参见 http://blog. ...

  4. 求最短路径(Bellman-Ford算法与Dijkstra算法)

    前言 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的算法来求 ...

  5. Canopy算法计算聚类的簇数

    Kmeans算是是聚类中的经典算法.步骤例如以下: 选择K个点作为初始质心 repeat 将每一个点指派到近期的质心,形成K个簇 又一次计算每一个簇的质心 until 簇不发生变化或达到最大迭代次数 ...

  6. 关于apriori算法的一个简单的例子

    apriori算法是关联规则挖掘中很基础也很经典的一个算法,我认为很多教程出现大堆的公式不是很适合一个初学者理解.因此,本文列举一个简单的例子来演示下apriori算法的整个步骤. 下面这个表格是代表 ...

  7. Floyd-Warshall算法计算有向图的传递闭包

    Floyd-Warshall算法是用来求解所有结点对最短路径的知名算法,其还有一个重要的用途就是求解有向图的传递闭包,下面就让我来介绍算法导论中关于有向图闭包计算的有关记载吧. 有向图的传递闭包:我们 ...

  8. 通过python的hashlib模块计算一个文件的MD5值

    Python的hashlib提供了很多摘要算法,如MD5,SHA1等常用算法. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(如MD5值 ...

  9. ZT 计算一个无符整数中1Bit的个数(1) 2010-04-20 10:52:48

    计算一个无符整数中1Bit的个数(1) 2010-04-20 10:52:48 分类: C/C++ [转]计算一个无符整数中1Bit的个数(1)   Count the number of bits ...

随机推荐

  1. Dynamics 365设置错误通知首选项的方法

    本人微信公众号:微软动态CRM专家罗勇 ,回复288或者20181205可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 使用 ...

  2. 关于Skyline沿对象画boundingbox的探讨

    先来说说为什么要搞这个?项目中经常遇到的一个操作就是选定对象,以前都是通过Tint设置对象颜色来标识选定对象,但是随着图层中模型增多,模型色彩丰富,会出现选定色与对象颜色对比不明显的情况.因为看到Te ...

  3. 动态BGP和静态BGP的含义与区别

    1.在华为云上选购虚拟机时,会让用户选择动态BGP还是静态BGP, 全动态BGP可根据设定的寻路协议第一时间自动优化网络结构,以保持客户使用的网络持续稳定.高效. 静态BGP中的网络结构发生变化,运营 ...

  4. iOS----------APP怎样做更安全

    1 网络请求的安全方案 1.1 https请求,最好有安全交互平台. 1.2 对重要的参数请求进行加密(推荐AES,ERSA加密). 1.3 服务器返回数据时,对重要数据进行加密. 1.4 不要把密钥 ...

  5. android找不到aar包

    转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/9939663.html  在做项目的时候引入aar包,编译的时候却提示错误(这个错误大概说的是...... ...

  6. Android EditText常用属性

    一.EditText介绍 ①EditText是一个输入框,在Android开发中是常用的控件.也是获取用户数据的一种方式. ②EditText是TextView的子类,它继承了TextView的所有属 ...

  7. delphi做的程序如何连接SQL数据库

    1. 新建一个FORM.在控件栏找到ADO一栏,把里面的ADOConnection和ADOQuery两个各建立一个放在FORM里.这两个控件运行后是不可见的,所以你可以随便放在FORM的任何位置.然后 ...

  8. 使用Python的列表推导式计算笛卡儿积

    笛卡儿积: 笛卡儿积是一个列表, 列表里的元素是由输入的可迭代类型的元素对构 成的元组,因此笛卡儿积列表的长度等于输入变量的长度的乘积, 如下图: 如果你需要一个列表,列表里是 3 种不同尺寸的 T ...

  9. C#-事件event

    目录 1. 简介 2.实际案例 2.1实际案例1 2.2实际案例2--带有参数的事件 3.标准事件的用法 3.1通过扩展EventArgs来传递数据 3.2代码实例 1. 简介 事件是一种类型安全的委 ...

  10. 【PAT】A1034Head of a Gang

    昨天准备学完图相关的知识,但是学起来挺懵的,理解起来不难,但自己一回想,又什么都想不起来. 翻来覆去看图的遍历,还是觉得有点没到位. 所以做题来检测一下,果然学和自己做是两码事. 先看的书,又看的柳婼 ...