美文网首页算法
Bellman-Ford算法的队列优化——SPFA算法

Bellman-Ford算法的队列优化——SPFA算法

作者: codinRay | 来源:发表于2017-04-11 10:04 被阅读0次

    Bellman-Ford算法中的松弛操作必定只会发生在最短路径前导节点松弛成功过的节点上,用一个队列记录松弛过的节点,可以避免了冗余计算。复杂度可以降低到O(kE),k是个比较小的系数(并且在绝大多数的图中,k<=2,然而在一些精心构造的图中可能会上升到很高)。

    // Bellman-Ford Algorithm queue optimization
    // SPFA
    #include <iostream>
    #include <queue>
    #include <algorithm>
    using namespace std;
    const int MAXV = 105;
    const int MAXE = 10005;
    const int INF = 0x3f3f3f3f;
    
    struct edge {
        int to;
        int cost;
    };
    int v, e;
    vector<vector<edge> > g(MAXV);
    int d[MAXV];
    queue<int> q;
    bool vis[MAXV];
    
    edge tempEdge(int t, int c) {
        edge ret;
        ret.to = t;
        ret.cost = c;
        return ret;
    }
    void SPFA(int s) {
        fill(d + 1, d + v + 1, INF);
        fill(vis + 1, vis + v + 1, false);
    
        d[s] = 0;
        vis[s] = true;
        q.push(s);
    
        while (!q.empty()) {
            int curV = q.front();
            q.pop();
            vis[curV] = false;
            
            for (edge E : g[curV]) {
                if (d[E.to] > d[curV] + E.cost) {
                    d[E.to] = d[curV] + E.cost;
                    if (!vis[E.to]) {
                        vis[E.to] = true;
                        q.push(E.to);
                    }
                }
            }
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(false);
        while (cin >> v >> e && v && e) {
            for (int i = 1; i <= v; ++i)
                g[i].clear();
            for (int i = 1; i <= e; ++i) {
                int f, t, c;
                cin >> f >> t >> c;
                g[f].push_back(tempEdge(t, c));
                g[t].push_back(tempEdge(f, c));
            }
            SPFA(1);
            cout << d[v] << endl;
        }
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:Bellman-Ford算法的队列优化——SPFA算法

        本文链接:https://www.haomeiwen.com/subject/ibdyattx.html