zoukankan      html  css  js  c++  java
  • SPFA算法模板

    SPFA是队列优化后的Bellman-Ford,用于求带负权边的最短路,然而传说中O(k*n)的复杂度好像是错误的。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<string>
     5 #include<set>
     6 #include<queue>
     7 using namespace std;
     8 #define INF 0x3f3f3f3f
     9 #define M(a, b) memset(a, b, sizeof(a))
    10 const int maxn = 1000 + 5;
    11 
    12 struct Edge {
    13     int from, to, dist;
    14 };
    15 
    16 struct SPFA {
    17     int d[maxn], cnt[maxn], p[maxn];
    18     int n, m;
    19     bool inq[maxn];
    20     vector<int> G[maxn];
    21     vector<Edge> edges;
    22 
    23     void init(int n) {
    24         this->n = n;
    25         for (int i = 1; i <= n; ++i) G[i].clear();
    26         edges.clear();
    27     }
    28 
    29     void AddEdge(int from, int to, int dist) {
    30         edges.push_back(Edge{from, to, dist});
    31         int m = edges.size();
    32         G[from].push_back(m-1);
    33     }
    34 
    35     bool spfa(int s) {
    36         M(d, INF); M(cnt, 0); M(inq, 0);
    37         d[s] = 0;
    38         queue<int> q;
    39         q.push(s);
    40         inq[s] = true;
    41         while (!q.empty()) {
    42             int u = q.front(); q.pop();
    43             inq[u] = false;
    44             for (int i = 0; i < G[u].size(); ++i) {
    45                 Edge &e = edges[G[u][i]];
    46                 if (d[e.to] > d[u] + e.dist) {
    47                     d[e.to] = d[u] + e.dist;
    48                     p[e.to] = G[u][i];
    49                     if (!inq[e.to]) {
    50                         q.push(e.to); inq[e.to] = true; 
    51                         if (++cnt[e.to] > n) return false;
    52                     }
    53                 }
    54             }
    55         }
    56         return true;
    57     }
    58 
    59 };
    60 
    61 SPFA solver;
    62 
    63 int main() {
    64     int n, m, a, b, c;
    65     while(cin >> m >> n) {
    66         solver.init(n);
    67         while(m--) {
    68             cin >> a >> b >> c;
    69             solver.AddEdge(a, b, c);
    70             solver.AddEdge(b, a, c);
    71         }
    72         solver.spfa(1);
    73         cout << solver.d[n] << endl;
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    测试文件报告
    Bug Variations
    阶段一 问答题2
    阶段一 问答题1
    HeapSort
    Git系列 (01):git clone 速度太慢解决方法
    ES6系列 (03):链判断运算符和Null 判断运算符
    ES6系列 (02):解构赋值
    ES6系列 (01):箭头函数this指向问题
    我忘却了所有,抛却了信仰,舍弃了轮回,只为,那曾在佛前哭泣的玫瑰,早已失去旧日的光泽。
  • 原文地址:https://www.cnblogs.com/robin1998/p/6602395.html
Copyright © 2011-2022 走看看