spfa---单源最短路存在负边无负环问题

spfa是bellman-ford算法的一个优化,就是在bellman-ford算法基础上进行了广搜,怎么优化的呢?我们来看bellman-ford算法:n点m边
其实就是在枚举n次的时候枚举每个边,比如 存入两点以及边权时,
设有5次操作
2 3 2
1 2 -3
1 5 5
4 5 2
3 4 3
那么初始化dist时就为 0 +∞ +∞ +∞+∞
第一次更新边 2 3 由于 dist[2]=+∞ dist[3]=+∞ dist[2]+2还是+∞所以未能松弛成功,枚举第二次 dist[1]=0,dist[2]=+∞ 所以成功更新dist[2]=-3;第二次枚举点的时候再次更新2 3因为此时dist[2]已经为-3,dist[3]=dist[2]+2=-1;所以可以完成松弛操作
那这样其实会有很多不必要的遍历边,所以我们遍历点的时候直接把和点相连的边如果它能更新当前点的值那么就把它加入队列,这样每次保证用到的都是操作的,提高效率

由于用到了邻接表所以看一下邻接表的操作
某伟把我的博客和别人的比了一番,所以我多加了很多注释
代码中注释↓

#include<iostream>
#include <vector>
#include<algorithm>
#include <queue>
#include<cstring>

using namespace std;

const int N = 100010,M=100010; 


int n,m;
int h[N],w[M],e[M],ne[M],idx;
//h[N] 邻接表相当于是N个单链表,所以h[i]数组表示以点i为起点能到达的点
//w[M] 表示边的权值、
//e[M] 表示指针指向到达的点a➡b
//ne[M]表示h指向的上一个点
//idx 指针每次++
int q[N], dist[N];
bool st[N];


void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;//e存入下一个点,w存权值,ne存上一个点 h更新上一个点
}
int spfa()
{
    queue<int> q;
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    q.push(1);
    st[1]=true;
    while(q.size())
    {
        int t=q.front();
        q.pop();
        st[t]=false;
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+w[i])
            {
                dist[j]=dist[t]+w[i];
                if(!st[j])
                {
                    q.push(j);
                    st[j]=true;
                }
            }
        }
    }
    return dist[n];
}
using namespace std;
int main()
{
    scanf("%d%d",&n,&m);
    memset(h,-1,sizeof h);
    while(m--)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    
    int t=spfa();
    if(t==0x3f3f3f3f)
    cout<<"impossible"<<endl;
    else
    {
        cout<<t<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值