关于SPFA——他复活了? || 最短路算法 SPFA + 堆 = Dijkstra?

网上讲解又多又好 模板的话也不错(虽然没我的好但我现在SPFA都不打裸的了)

这里就提供一种思路 SPFA + 堆优化 跑的快快哒

不过感觉全世界的毒瘤出题人都还会想方设法地卡SPFA 具体原因 百度 “卡SPFA” 然后随便进去就行了

的确嘛 这算法都不正经= =

然后dalao们都是改用优先队列存点的 但是死不用 STL 的 Frocean……

于是这里采用堆存储(堆和优先队列不是同一个东西吗) 关于距离数组 dis 用小根堆维护 每次取dis最小的点更新 等根里没数了就跑完了

然后据一些人所说我这个不是SPFA了??但我只是加了个堆啊QvQ 当然我去翻了下迪杰斯特拉的板子 貌似也是这样拓展的 如果真的是的话那就……自然是更好的了 然而我真没学过迪杰斯特拉啊QAQ 我只是把我的SPFA队列换成堆了啊….

一般图优化效果也比较明显 普通模板快了 50ms 然后稠密图优化效果极其显著 但是如果卡这种做法的图那就完了 虽然我没见过

我还是觉得就是 SPFA 就不批注了 存个代码警示一下 卡SPFA的题戳这里

#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 100010;
const int MAXM = 400010;
struct Edge {
    int next,to,v;
} e[MAXM];
int first[MAXN],dis[MAXN],heap[MAXN],tot;
short o[MAXN];
void add(int x,int y,int z)
{
    e[++tot].next = first[x];
    e[tot].to = y;
    e[tot].v = z;
    first[x] = tot;
}
void push(int p)
{
    heap[++tot] = p;
    o[p] = 1;
    int now = tot;
    while (now > 1 && dis[heap[now]] < dis[heap[now / 2]])
    swap(heap[now],heap[now / 2]),now = now / 2;
}
int pop(int p)
{
    o[heap[1]] = 0;
    int po = heap[1];
    heap[1] = heap[tot--];
    while (p * 2 <= tot && dis[heap[p]] > dis[heap[p * 2]] ||
      (p * 2 + 1 <= tot && dis[heap[p]] > dis[heap[p * 2 + 1]]))
    {
        int nxt = p * 2;
        if (nxt + 1 <= tot && dis[heap[nxt]] > dis[heap[nxt + 1]]) ++nxt;
        swap(heap[p],heap[nxt]);
        p = nxt;
    }
    return po;
}
int main()
{
    memset(dis,0x7f,sizeof(dis));
    int n,m,s,x,y,z;
    scanf("%d%d%d",&n,&m,&s); while (m--)
    scanf("%d%d%d",&x,&y,&z),add(x,y,z);
    tot = 0;
    push(s);
    dis[s] = 0;
    while (tot)
    {
        int p = pop(1);
        for (int a = first[p],b = e[a].to ; a ; a = e[a].next,b = e[a].to)
            if (dis[p] + e[a].v < dis[b])
            {
                dis[b] = dis[p] + e[a].v;
                if (!o[b]) push(b);
            }
    }
    for (int a = 1 ; a < n ; ++ a)
    printf("%d ",dis[a]);
    printf("%d\n",dis[n]);
    return 0;
}

 

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/Frocean/article/details/81569304
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞