目录
  1. 基本思路
  2. 代码
【模板】Dijkstra算法+链式前向星+堆优化
  • 时间复杂度:
    Dijkstra: $O(n^2)$
    Dijkstra+优先队列: $O (2 E + V logV)$

基本思路

  • 指定起点s,即从顶点s开始计算。
  • 集合S:记录已求出最短路径的顶点(以及相应的最短路径长度),
  • 集合U:记录还未求出最短路径的顶点(以及该顶点到起点s的距离)
  1. 初始时,S中只有起点s;U中是除s之外的顶点。U中顶点的路径是”起点s到该顶点的路径”。
  2. 然后,从U中找出路径最短的顶点v,并将其加入到S中。更新U中的顶点(及顶点对应的路径)。
  3. 再从U中找出路径最短的顶点,并将其加入到S中。
  4. 重复该操作,直到遍历完所有顶点。

  • 单源最短路,当权值非负时可以用Dijkstra

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <bits/stdc++.h>
using namespace std;

const int maxn = 100005;
const int maxm = 200005;

inline const int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}

int vis[maxn], dis[maxn], head[maxn];

struct edge{
int v,w,next;
}e[maxm];

int cnt = 0;

struct node{
int u,w;
bool operator <(const node & a) const{ return w>a.w; }
};

void addedge(int u, int v, int w)
{
e[cnt].v = v;
e[cnt].w = w;
e[cnt].next = head[u];
head[u] = cnt++;
}

priority_queue<node> q;

void dijkstra(int s)
{
memset(dis, 0x3f, sizeof dis);
memset(vis, 0, sizeof vis);
dis[s] = 0;
q.push(node{s, 0});
while(!q.empty()){
int u = q.top().u;
q.pop();
if(vis[u]) continue;
else vis[u] = 1;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v = e[i].v, w = e[i].w;
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push(node{v, dis[v]});
}
}
}
}

int main()
{
memset(head, -1, sizeof head);
int n = read(), m = read(), s = read();
while(m--)
{
int u = read(), v = read(), w = read();
addedge(u, v, w);
}
dijkstra(s);
for(int i=1;i<=n;i++)
printf("%d%c", dis[i], (i==n)?'\n':' ');
return 0;
}
文章作者: Irimsky
文章链接: /2019/10/12/【模板】Dijkstra算法-链式前向星-堆优化/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Irimsky's Blog

评论