树
树的定义与概念
树的表示与存储
二叉树
二叉树的遍历
图论
图的定义和概念
图的存储
图的遍历
最短路径问题 Dijkstra
经典例题:
#include <bits/stdc++.h>
using namespace std;
// 1. 存图,边的信息保存 vector 数组
// 2. Dijkstra 算法:建立距离起点的表格,把所有的距离初始化为 inf (无穷远),起点标记为 0
// a. 提取距离起点最近的顶点(未访问)
// b. 求它可以去的所有顶点 最短值计算 road,road < d[顶点] 更新最短路径
// c. 重复 a,b 直到所有的顶点没有扩散的点
// 3. 得到 d 数组 距离起点的所有顶点的最短距离
struct EDGE {
int v, w; // 到达的 v 终点,w 权值,v 表示顶点的编号,w 还表示 d[v] 距离
bool operator < (const EDGE &a) const {
return a.w < w; // w 值越小的 排在前面
}
};
const int MAXN = 2e5 + 5;
vector<EDGE> g[MAXN]; // 最多 2e5 个顶点
int n, m, s, t, dist[MAXN]; // n 个顶点,m 条边,s 起点,t 终点,dist 记录起点到其他所有点最短距离 distance
void Dij() {
// 建立距离起点的表格,把所有的距离初始化为 inf (无穷远),起点标记为 0
memset(dist, 0x3f, sizeof(dist));
dist[s] = 0;
priority_queue<EDGE> q; // 优先队列,每次提取距离起点最近的顶点
q.push({s, dist[s]}); // 把起点和到起点的距离放入优先队列
while (!q.empty()) {
// a. 提取距离起点最近的顶点(未访问)
EDGE now = q.top(); q.pop();// 取出最近的距离
int u = now.v, w = now.w; // 这个顶点编号保存 u,s 到 u 距离是 w
if (w > dist[u]) continue; // 当此时这个顶点的 w 比现在记录 dist[u] 还要远,没有意义的扩展
// b. 求它可以去的所有顶点 最短值计算 road,road < d[顶点] 更新最短路径
for (auto e : g[u]) {
int v = e.v, road = dist[u] + e.w; // 先从起点走到这个 u 点,从 u 点走到 v
if (road < dist[v]) { // 发现此时走这条路更进
dist[v] = road;
q.push({v, dist[v]}); // 松弛操作,将这个更新的点放入到优先队列中
}
}
}
}
int main() {
// 1. 存图,边的信息保存 vector 数组
cin >> n >> m >> s >> t; // 按照顺序输入
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c; // 起点 a 到 b 距离需要 c
g[a].push_back({b, c});
g[b].push_back({a, c}); // 双向图从 b 到 a 需要 c
}
// 2. Dijkstra 算法
Dij();
// 3. 得到 d 数组 距离起点的所有顶点的最短距离 起点 s 到 t 最短距离
cout << dist[t]; // t 点距离 s 点最短距离
return 0;
}