单源最短路 狄克斯特拉算法

一般形式的用邻接矩阵来实现dijkstra效率比较低,我这里直接记录的是用邻接表的方法以及用优先队列加以应用。

首先解释什么是dijkstra算法

dijkstra算法

dijkstra算法适用于求单源最短路,即可以求出起点到其余各点之间的最短路。它的算法实现是一个不断更新的过程。

举一个最简单的例子,假设有这么一个图,红色表示权值,黑色表示4个点以及路径,我们假设起点为1,用d[i]来表示1到i的最短路,那么在第一轮的时候,d[2]=1,d[3]=1,d[4]=5,再下一轮的时候会对这个情况进行更新,结果为d[2]=1,d[3]=1,d[4]=4,以此类推,会一直更新到d[2]=1,d[3]=1,d[4]=3为止,所以我认为该算法是一个不断更新的过程。

邻接表表示法

邻接表表示法我们使用vector以及pair两种工具,可以极大的节省空间以及算法实现中遍历搜索的时间,举一个例子

该图的邻接表表示为,具体实现可以看代码

洛谷P1346

解题思路大概就是把默认指向的轨道的权值设为0,需要开关的轨道权值设为1。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <stdio.h>
 8 #include <cmath>
 9 #include <string.h>
10 using namespace std;
11 #define ll long long
12 static const int WHITE=0;//未选
13 static const int GRAY=1;//备选
14 static const int BLACK=2;//已选
15 static const int INFTY=(1<<20);
16 int N,A,B;
17 vector<pair<int,int> > adj[105];//加权图的邻接表表示法
18 void dijkstra()
19 {
20     priority_queue<pair<int,int> > que;//用优先队列,first表示路径成本,second表示路口
21     int color[105],d[105];
22     for(int i=1;i<=N;i++)//初始化
23     {
24         d[i]=INFTY;
25         color[i]=WHITE;
26     }
27     d[A]=0;//设置起点
28     que.push(make_pair(0,A));
29     color[A]=GRAY;
30     while (!que.empty())
31     {
32         pair<int,int> f=que.top();
33         que.pop();
34         int u=f.second;
35         color[u]=BLACK;
36         if(d[u]<f.first*(-1))//取出最小值,若不是最短路则忽略
37         continue;
38         for(int j=0;j<adj[u].size();j++)//更新最短路
39         {
40             int v=adj[u][j].first;
41             if(color[v]==BLACK)
42             continue;
43             if(d[v]>d[u]+adj[u][j].second)
44             {
45                 d[v]=d[u]+adj[u][j].second;
46                 que.push(make_pair(d[v]*(-1),v));//因为优先队列默认优先较大值,所以乘以-1
47                 color[v]=GRAY;
48             }
49         }
50     }
51     if(d[B]==INFTY)
52     cout<<"-1"<<endl;
53     else
54     {
55         cout<<d[B]<<endl;
56     }
57
58 }
59 int main()
60 {
61     //freopen("C:\\Users\\16599\\Desktop\\in.txt","r",stdin);
62     scanf("%d%d%d",&N,&A,&B);
63     for(int i=1;i<=N;i++)
64     {
65         int K,a;
66         scanf("%d",&K);
67         if(K!=0)//注意k可能为0
68         {
69             scanf("%d",&a);
70             adj[i].push_back(make_pair(a,0));//表示第i个路口默认通向第a个路口,权值为0
71         }
72         for(int j=2;j<=K;j++)
73         {
74             scanf("%d",&a);
75             adj[i].push_back(make_pair(a,1));//表示第i个路口通向第a个路口需要按开关,权值为1
76         }
77     }
78     dijkstra();
79     return 0;
80 }

原文地址:https://www.cnblogs.com/zlhdbk/p/11255602.html

时间: 2024-10-09 02:45:31

单源最短路 狄克斯特拉算法的相关文章

图算法——狄克斯特拉算法

这里有一些定义及代码取自CodeInfo的简书,链接:https://www.jianshu.com/p/b805e9d1eb5c,和heroacool的CSDN,链接:https://blog.csdn.net/heroacool/article/details/51014824,感谢两位大佬. 狄克斯特拉算法(Dijkstra )用于计算出不存在非负权重的情况下,起点到各个节点的最短距离(单源最短路问题),如果要得到整个图各个顶点之间的最短距离,则需要对整个图的每个顶点都遍历一遍狄克斯特拉算

最短路径--Dijkstra(狄克斯特拉)算法

最短路径 路径的概念:       在一个无权的图中,若从一顶点到另一顶点存在着一条路径,则称该路径长度为该路径上所经过的边的数目,它等于该路径上的顶点数减1.       由于从一顶点到另一顶点可能存在着多条路径,每条路径上所经过的边数可能不同,即路径长度不同,我们把路径长度最短(即经过的边数最少)的那条路径叫做最短路径,其路径长度叫做最短路径长度或最短距离.       对于带权的图,考虑路径上各边上的权值,则通常把一条路径上所经边的权值之和定义为该路径的路径长度或称带权路径长度.     

算法之狄克斯特拉算法 --《图解算法》

2019你好!好好生活,好好工作! 狄克斯特拉算法 狄克斯特拉算法(Dijkstra )用于计算出不存在非负权重的情况下,起点到各个节点的最短距离 可用于解决2类问题: 从A出发是否存在到达B的路径:从A出发到达B的最短路径(时间最少.或者路径最少等),事实上最后计算完成后,已经得到了A到各个节点的最短路径了:其思路为: (1) 找出"最便宜"的节点,即可在最短时间内到达的节点. (2) 更新该节点对应的邻居节点的开销,其含义将稍后介绍. (3) 重复这个过程,直到对图中的每个节点都这

狄克斯特拉算法

狄克斯特拉算法用于在加权图中查找最短路径. 仅当权重为时算法才管用,如果图中包含负权边,请使用贝尔曼-福得算法. # 有向无环图 graph = {} graph["start"] = {} graph["start"]["a"] = 6 graph["start"]["b"] = 2 graph["a"] = {} graph["a"]["fin"

数据结构之单源最短路径(迪杰斯特拉算法)-(九)

最开始接触最短路径是在数据结构中图的那个章节中.运用到实际中就是我在大三参加的一次美赛中,解决中国的水资源问题.所谓单源最短路径,就是一个起点到图中其他节点的最短路径,这是一个贪心算法. 迪杰斯特拉算法原理(百科): 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的集合(初始时只含有源点V0) (2)V-S=T:尚未确定的顶点集合 将T中顶点按递增的次序加入到S中,保证: (1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度 (2)每个顶

狄克斯特拉算法(图的最短路问题)

该算法思想就是   1)首先找离起点最近的点 2)然后对该点进行标记,并且对与该点相邻的点进行松弛(也就是更新周围点离起点的距离最小值) 3)继续找更新之后的图中离起点最近的未被标记的点 具体的实现方式有两种: 方式一时间复杂度是O(n^2),具体实现方式是通过两个for循环实现(其中内层循环负责找最近点以及遍历更新最近点附近的点,外层循环负责维持内层遍历的持续进行) 方式二时间复杂度是O(m*logn),具体实现是利用bfs结合优先队列来实现(优先队列代替了内层循环,bfs代替了外层for循环

【裸单源最短路:Dijkstra算法两种版本】hdu 1874 畅通工程续

Source : hdu 1874 畅通工程续 http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离. Input 本题目包含多组数据,请处理到文件结束.

Dijkstra算法 --- 单源最短路

Dijkstra算法适用于边权值为正的情况,可用于计算正权图上的单元最短路. 其伪代码如下: 设d[v0] = 0, 其他d[i] = INF 循环n次{ 在所有未标号的结点中,选取d值最小的结点x 给结点x加上永久标号 对于从x出发的所有边,执行松弛操作. } //松弛操作的伪代码如下: RELAX(u,v,w) if(u.d + w(u,v) < v.d){ v.d = w.d + w(u,v); pre[v] = u; } Dijkstra算法代码: /* Dijkstra 单源最短路算法

再看最短路算法 1 —— 单源最短路

学了多年的算法,最短路问题相当之常见———— 好久没写过最短路的问题了,直到昨天闲的无聊来了一题——BZOJ3402(HansBug:额才发现我弱到只能刷水的地步了TT) 一看这不是明显的单源最短路么呵呵...于是直接上来来了个dijkstra,而且用的是邻接表存储图—— Submit之后,结果却是—— 我立刻被雷到了QAQ...于是立刻改写spfa,结果—— 4000ms+(估计还不止)和192ms究竟是怎样的差距啊QAQ,本人虽然早都听说过spfa的强大性,但是未曾想过差距会如此可怕,于是H