再会迪杰斯特拉(Dijkstra)
迪杰斯特拉算法
算法说明
迪杰斯特拉算法用来求解某一个起点到以其他所有点为终点的最短路径长度;
算法思路-贪心算法
以下图为例
- 指定一个节点(即起点),例如计算“A”到其他节点的最短路径;
- 引入两个集合(S,U),S集合包含所有已经求出其最短路径的点(以及其最短长度),U集合包括未求出的最短路径的点;
所有和起点A直接相连的节点更新其与A的距离为路径长度,没有直接相连的设置为+∞;
- 从U集合中找出距离起点s路径最短的点,加入S集合,例如第一步最小的为A->D,距离为2;
- 更新U集合路径,if(A->D+D->(B、C、E))(B、C、E),就更新U;
- 重复执行横线内两步,直到所有的节点都被加到了集合U中;
下面使用迪杰斯特拉算法处理上图
①选取起点为A,首先刷新所有和A点直接通过边相连的点,即B、D点,将A->D置为2,A->B置为4,其他A->C,A->E均为正无穷
算法代码
#include <stdio.h>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <string.h>
#include <stdlib.h>
#define N 100005
#define INF 2147483647
typedef long long ll;
using namespace std;
typedef struct Edge {ll to;ll wei;Edge() {to=-1;wei=INF;//初始都为不可达状态}
} E;
ll n,M,s;
vector<E>m[N]; //邻接表
bool wh[N]; //集合U和S,true代表节点已经放入S,false表示还在U集合
ll dis[N]; //存放起点到节点的最短距离
ll cnt; //S集合元素个数
void Dijkstra(int s)
{wh[s]=true;cnt++;while (cnt!=n) {int Min=INF,Minindex=-1;//开始找S集合中距离s最近的节点for (int i=1; i<=n; i++) {if (!wh[i]&&(dis[i]<Min)) {Min=dis[i];Minindex=i;}}//此时找到了最小的边//将此节点放到S集合wh[Minindex]=true;cnt++;//更新U集合路径for (int i=0; i<m[Minindex].size(); i++) {dis[m[Minindex][i].to]=min(m[Minindex][i].wei+dis[Minindex],dis[m[Minindex][i].to]);}}
}
int main()
{cin>>n>>M>>s;for (int i=1; i<=n; i++) {if(i==s) {dis[s]=0;} else {dis[i]=INF;}}ll f,t,w;for (ll i=1; i<=M; i++) { //存储图 cin>>f>>t>>w;int flag=0;//有向图,不双向 for (int j=0; j<m[f].size(); j++) { //重边 if (m[f][j].to==t) {m[f][j].wei=min(w,m[f][j].wei);flag=1;break;}}if (flag==0) {E e;e.to=t;e.wei=w;m[f].push_back(e);}}//找到和起点直接相连的节点,设置和起点直接相连的距离for (int i=0; i<m[s].size(); i++) {dis[m[s][i].to]=m[s][i].wei;}Dijkstra(s);for (int i=1; i<=n; i++) {if (i==s) {(i==1)?cout<<0:cout<<" "<<0;continue;}(i==1)?cout<<dis[i]:cout<<" "<<dis[i];}
}
上述算法即是最朴素的迪杰斯特拉算法,需要注意的是,算法考虑了顶点有重边的情况,这是洛谷的题目要求的,题目链接:
P3371 【模板】单源最短路径(弱化版)
但对于没有优化的迪杰斯特拉算法,题目的强化版就会直接TLE,分析朴素的Dijkstra算法,我们发现可以优化的点有:
- 每次寻找U集合中dis中最小的元素时使用了遍历的方法,但我们可以使用小顶堆保证每次直接弹出最小的值,不需要再去遍历;
对于优先队列,使用stl库的priority_queue实现。
迪杰斯特拉算法的优缺点
- 优点
- 算法思路简单,比较容易上手使用;
- 经典的最短路算法,适合大多数场景;
- 缺点
- 时间复杂度和其他算法相比不太理想,适用于节点n不太多的情况;
- 不能处理存在总花费为负值且从源点S可达的环路的图,因为显然无限兜圈子花费会越来越小;
- 事实上,存在负环的情况是抓住了贪心算法的弱点导致问题不能解决;
再会迪杰斯特拉(Dijkstra)相关推荐
- 数据结构与算法(7-4)最短路径(迪杰斯特拉(Dijkstra)算法、弗洛伊德(Floyd)算法)
目录 一.最短路径概念 二.迪杰斯特拉(Dijkstra)算法(单源最短路径) 1.原理 2.过程 3.代码 三.弗洛伊德(Floyd)算法(多源最短路径) 1.原理 2.存储 3.遍历 4.代码 参 ...
- 059.迪杰斯特拉(Dijkstra)算法的原理以及解决最短路径问题
1. 迪杰斯特拉(Dijkstra)算法的原理 1.1. 算法应用场景-最短路径问题 1.2. 基本介绍 1.3. 步骤详解 1.4. 思路解析 1.5. 图解步骤 2. 迪杰斯特拉(Dijkstra ...
- java数据结构和算法——迪杰斯特拉(Dijkstra)算法
目录 一.迪杰斯特拉(Dijkstra)算法介绍 二.迪杰斯特拉(Dijkstra)算法过程 三.迪杰斯特拉(Dijkstra)算法--应用场景(最短路径问题) 四.迪杰斯特拉(Dijkstra)算法 ...
- 迪杰斯特拉(Dijkstra)算法解决最短路径问题
Dijkstra 算法介绍 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法.迪杰斯特拉(Dijkstra)算法是最经典的最短路径算法之一,用 ...
- c语言迪杰斯特拉算法求最短路径,迪杰斯特拉 ( Dijkstra ) 最短路径算法
迪杰斯特拉算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径.它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本 ...
- 最短路径算法-迪杰斯特拉(Dijkstra)算法
最短路径算法-迪杰斯特拉(Dijkstra)算法 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思 ...
- Java迪杰斯特拉(Dijkstra)算法与弗洛伊德(Floyd)算法
1.Java迪杰斯特拉(Dijkstra)算法与弗洛伊德(Floyd)算法 1.1 迪杰斯特拉(Dijkstra)算法 1.1.1 迪杰斯特拉(Dijkstra)算法介绍 迪杰斯特拉(Dijkstra ...
- java实现迪杰斯特拉(Dijkstra)算法求解最短路问题
迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的.是寻找从一个顶点到其余各顶点的最短路径算法,可用来解决最短路径问题. 迪杰斯特拉算法采用贪心算法的策略,将所有顶点分 ...
- 数据结构——图——迪杰斯特拉(Dijkstra )算法
数据结构--图--迪杰斯特拉(Dijkstra )算法 这是一个按路径长度递增的次序产生最短路径的算法.它的思路大体是这样的. 比如说要求图7-7-3中顶点v0到顶点v1的最短距离,没有比这更简单的了 ...
最新文章
- 【DP】[NOI2013]书法家
- 使用Java高速实现进度条
- plsql轻量版存储过程和存储函数
- 爬虫教程( 4 ) --- 分布式爬虫 scrapy-redis、集群
- c语言的指针详解ppt,最全的C语言指针详解.ppt
- 理解sklearn.feature.text中的CountVectorizer和TfidfVectorizer
- mysql jndi 实例_自己收藏-JNDI应用实例
- GEE学习总结(4)——CSV数据上传、读取和操作
- Vue实现CNode
- Jenkins清空当前Clean Workspace
- Jensen不等式简介
- 超酷!Python 绘制属于你的世界地图
- JVM内存结构(1.8)
- 期权定价模型之Merton模型的校准与定价【python量化】
- PHP字符串函数strtolower(将字符串转化为小写)
- VUE解决warning(Emitted value instead of an instance of Error) el-table-column v-for=item in batch问题
- 加字邮票价格_SC2 “华东区生产图邮票”加字改值 价格收藏图片
- EasyPR-Java新能源车牌识别
- SPAMS Matlab 安装
- slice,splice,substring,split