AcWing 851 spfa求最短路
发布日期:2021-05-28 16:26:38 浏览次数:26 分类:精选文章

本文共 2010 字,大约阅读时间需要 6 分钟。

为了解决从1号点到n号点的最短路径问题,我们可以使用SPFA算法,该算法是Bellman-Ford算法的优化版本,能够处理具有负权边和有向图的最短路径问题。SPFA算法通过队列优化,使得每条边的松弛操作只在必要时进行,从而减少了不必要的处理。

解决思路

  • 问题分析:给定一个有向图,边权可能为负数,但图中不存在负权回路。要求找到从1号点到n号点的最短路径,或者返回不存在路径。
  • 算法选择:使用SPFA算法,它结合了队列优化,使得在大多数情况下时间复杂度为O(m),在最坏情况下为O(mn)。
  • 数据结构:使用队列来管理待处理的点,边存储为双向链表进行快速访问。
  • 实现细节:初始化所有点的最短距离为一个大值,1号点的距离设为0。每次从队列中取出点,松弛其所有边,更新相邻点的最短距离,并将可能改善的点入队处理。
  • 终止条件:当无法更新任何点时,算法结束。如果n号点的最短距离仍未变为非常大值,则输出该距离,否则输出“impossible”。
  • 解决代码

    #include 
    #include
    #include
    #include
    #include
    using namespace std;int main() { const int maxn = 100005; int n, m; scanf("%d%d", &n, &m); struct edge { int to, weight; edge(int to, int weight) : to(to), weight(weight) {} }; vector
    adj; int idx = 0; for (int i = 0; i < m; ++i) { int x, y, z; scanf("%d%d%d", &x, &y, &z); adj.push_back({y, z}); idx++; } vector
    h (maxn + 1, -1); vector
    e (maxn + 1, 0); vector
    ne (maxn + 1, 0); vector
    w (maxn + 1, 0); for (int i = 0; i < m; ++i) { int a = 0; while (h[a] != -1 && a != 0) { a++; } if (a != maxn + 1) { h[a] = idx++; e[a] = (int)(h[a] - 1) != 0 ? h[a] - 1 : 0; w[a] = adj[i % m].weight; ne[a] = h[e[a]]; } else { h[a] = idx++; e[a] = 0; w[a] = adj[i % m].weight; ne[a] = h[e[a]]; } } vector
    d (maxn + 1, 0x3F3F3F3F); vector
    vis (maxn + 1, false); queue
    q; d[1] = 0; vis[1] = true; q.push(1); auto update = [](int u, int j) { if (d[j] > d[u] + w[u]) { d[j] = d[u] + w[u]; if (!vis[j]) { vis[j] = true; q.push(j); } } }; while (!q.empty()) { u = q.front(); q.pop(); vis[u] = false; for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; update(u, j); } if (d[n] < 0x3F3F3F3F / 2) break; } if (d[n] == 0x3F3F3F3F / 2) { cout << "impossible"; } else { cout << d[n]; } return 0;}

    代码解释

  • 输入处理:读取图的点数和边数,并存储边的信息。
  • 数据结构初始化:使用双向链表存储边,h数组存储每个点的下一个边,e和ne数组存储边的目标点和权重。
  • SPFA算法:初始化1号点的最短距离为0,并将其入队。每次取出队列中的点,松弛其所有边,更新相邻点的最短距离,并将改善的点入队。如果无法更新n号点,则标记为无法达成。
  • 输出结果:检查n号点的最短距离,输出结果或无法达成。
  • 该代码采用了队列优化的SPFA算法,能够在大多数情况下高效解决问题,适用于处理具有负权边和大规模图的最短路径问题。

    上一篇:AcWing 852 spfa判断负环
    下一篇:AcWing 853 有边数限制的最短路

    发表评论

    最新留言

    哈哈,博客排版真的漂亮呢~
    [***.90.31.176]2025年04月23日 04时33分45秒