【笔记/模板】Dijkstra算法
原理解释
Dijkstra算法是通过贪心+BFS+动态规划实现的,可以用来计算单个点(源点)到其余任一点的距离大小。
Dijkstra算法的实现分为以下几步:
-
定义并初始化数组
dis[N]
,其中 \(dis_{i}\) 表示源点当前距离 \(i\) 点的最短距离,再定义一个 \(bool\) 数组vis[N]
, \(vis_{i}\) 代表第 \(i\) 个点是否被拓展过(即是否达到了最优解)。 -
从未被拓展的点中找出一个离源点最近的点 \(x\)(此时它已经是最优解),通过这个点依次松弛和它联通的每一个点距离源点的距离,同时将所松弛的点加入到队列当中。
-
等到队列中没有元素存在之后,结束函数,此时
dis[N]
中的每个点 \(dis_{i}\) 即代表着距离源点的最小距离。
代码实现
朴素法
struct Edge { int x, w; }; // x表示出点,w表示权值.
vector<Edge> g[N]; //存图数组
int dist[N]; //d[i]表示st距离i点的距离大小
void dijkstra(int st)
{
memset(dist, 0x3f, sizeof dist);
dist[st] = 0;
bitset<N> vis; // 初始化d数组全部变成无穷大,d[st]即表示与源点的距离为0
for (int i = 1; i <= n; i++)
{
int t = -1;
for (int j = 1; j <= n; j++)
if (t == -1 || (!vis[j] && dist[j] < dist[t]))
t = j; // 找出离源点最近的一个点
vis[t] = true; // 表示已经拓展过
// 此时 d[u] 一定是最优的
for (auto &y : g[t])
if (!vis[y.x] && d[y.x] > d[t] + y.w)
d[y.x] = d[t] + y.w;
}
}
队列 / 堆优化
vector 存图
struct Edge
{
int x, w; // x表示出点,w表示权值.
bool operator < (const Edge &u) const { return w > u.w; }
};
vector<Edge> g[N];
int dist[N];
void dijkstra(int st)
{
memset(dist, 0x3f, sizeof dist);
dist[st] = 0;
bitset<N> vis; // 初始化
priority_queue<Edge> heap;
heap.push({st, dist[st]}); // 将源点加入队列
while (heap.size())
{
int t = heap.top().x;
heap.pop();
if (vis[t]) continue;
vis[t] = true;
for (auto &y : g[t])
{
if (!vis[y.x] && dist[y.x] > dist[t] + y.w) // 如果vis[y]则说明y点已经被拓展到最优解,无需更新
{
dist[y.x] = dist[t] + y.w; // y点目前仍然不是最优的,不可以进行拓展
heap.push({y.x, dist[y.x]}); // 将y点加入队列中
}
}
}
}
链式前向星
struct Edge
{
int ver, val;
bool operator < (const Edge &rhs) const { return val > rhs.val; }
};
int n, m, st;
int h[N], e[M], ne[M], w[M], idx;
int dist[N];
bool vis[N];
void dijkstra(int st)
{
priority_queue<Edge> heap;
memset(dist, 0x3f, sizeof dist), memset(vis, 0, sizeof vis);
dist[st] = 0;
heap.push({st, 0});
while (!heap.empty())
{
auto [ver, val] = heap.top(); heap.pop();
if (vis[ver]) continue;
vis[ver] = true;
for (int i = h[ver]; ~i; i = ne[i])
{
int to = e[i];
if (dist[to] > dist[ver] + w[i])
{
dist[to] = dist[ver] + w[i];
heap.push({j, dist[j]});
}
}
}
}
标签:
笔记/模板
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!