Dijkstra算法
首先 , 给出 模板
:::success[Dijkstra]
struct edge {
int v, w;
};
struct node {
int dis, u;
bool operator>(const node& a) const { return dis > a.dis; }
};
vector<edge> e[MAXN];
int dis[MAXN], vis[MAXN];
priority_queue<node, vector<node>, greater<node>> q;
void dijkstra(int n, int s) {
memset(dis, 0x3f, (n + 1) * sizeof(int));
memset(vis, 0, (n + 1) * sizeof(int));
dis[s] = 0;
q.push({0, s});
while (!q.empty()) {
int u = q.top().u;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (auto ed : e[u]) {
int v = ed.v, w = ed.w;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
q.push({dis[v], v});
}
}
}
}
:::
最短路径
-
路径长度: 当图是带权图时,把从一个顶点i到图中其余任意一个顶点j的一条路径(可能不止一条)所经过边上的权值之和,定义为该路径的带权路径长度。
-
最短路径: 把带权路径长度最短的那条路径称为最短路径。
备注:求解最短路径的算法通常都依赖于一种性质,即两点之间的最短路径也包含了路径上其他顶点间的最短路径。
- 带权有向图G的最短路径问题一般可分为两类: (1)单源最短路径:求图中某一顶点到其他各顶点的最短路径。 (2)多源最短路径:求每对顶点间的最短路径。
单源最短路径-Dijkstra算法(迪杰斯特拉)
(1) Dijkstra整体思路:
Dijkstra算法设置一个集合S记录已求得的最短路径的顶点,初始时把源点
(2) 些符号说明:
-
邻接矩阵$arcs$表示带权有向图,$arcs[i][j]$表示有向边$<i,j>$的权值,若不存在有向边$<i,j>$则$arcs[i][j]$为$∞$。
(3) Dijkstra算法流程: (求解vo到其他节点的最短路径)
1) 初始化:集合S初始为
2) 2)从顶点集合
数组。
第二轮:选出最小值
第四轮:选出唯一最小值
(5)时间复杂度分析
邻接矩阵存储图
(6)不适用条件
当图中含有负权边时,