关于最短路算法

关于我写了一年堆优化的\(SPFA\)这件事

今天我研究为啥\(dij\)不能跑负边权这件事的时候

我的没有每个点只能进队一次的限制,然后我认为堆优化的\(dij\)也是可以跑负边的

于是乎我就懵逼了

后来发现堆优化的\(dij\)每个点只能进队一次,标上\(vis\),只能进一次(严谨一些是只能作为起点去更新别人一次,再次出现时就直接跳过就行了),也就是说必须保证当前点是距离最小的点

但是有负边权的话,就不能保证是距离最小的点了

于是乎我写的那个可以重复进队,于是是个四不像算法

怪不得我之前分析我自己的最短路复杂度的时候,总感觉多个常数

发现我的最短路,不仅可以重复进队,还没有\(vis\),战神叫它堆优化的\(SPFA\)

记住,\(dij\)每个点只能进队一次保证复杂度,\(SPFA\)每个点在队里就不用新加了

下面放上我的堆优化的\(SPFA\)

code
int dis[N];
struct node{
    int x,d;
    node(){}
    node(int a,int b){x=a;d=b;}
    bool operator < (node a)const{
        return d>a.d;
    }
};
priority_queue<node> q;
void dij(){
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;q.push(node(1,0));
    while(!q.empty()){
        int x=q.top().x;q.pop();
        for(int i=head[x];i;i=nxt[i]){
            int y=to[i];
            // cout<<endl<<"SB"<<" "<<x<<" "<<dis[x]<<" "<<len[i]<<" "<<y<<" "<<dis[y]<<endl;
            if(dis[y]<=dis[x]+len[i])continue;
            dis[y]=dis[x]+len[i];
            q.push(node(y,dis[y]));
        }
    }
}
posted @ 2021-12-20 08:43  fengwu2005  阅读(37)  评论(0编辑  收藏  举报