SPFA算法

SPFA算法是一种解决图中单源最短路径问题的算法,尤其适用于包含负权重边的情况。它通过队列进行操作,不断更新节点的最短路径,并在必要时将节点重新入队。虽然比Bellman-Ford算法更高效,但在最坏情况下仍可能达到O(VE)的时间复杂度。文章还提供了SPFA的实现代码和示例题目。
摘要由CSDN通过智能技术生成

SPFA算法:

主要是为了求解图中的单源最短路径(可以含负权边),是对Bellman-Ford 的优化,但无法完全取代Bellman-Ford。SPFA算法可以解决,Dijkstra算法无法解决的权值为负的情况。

为什么出现负权值dijkstra算法失效
在这里插入图片描述

我们看张图,从1号结点开始执行dijkstra算法,我们在权值6和5的边中选择权值为5的边此时来到二号结点d[2]=5,然后选择边权为-2的边更新d[3]=3,结束dijkstra算法。我们可以看到结束时d[2]=5,而实际上d[2]应该=4才是最短路径,也就是从1–>3–>2这样走才是最短的。这是因为dijkstra算法实际上是贪心算法,所以导致了错误的发生!

SPFA算法实现过程

我们用一个队列,每次拿去队首元素,先取消标记表示已经出队,然后遍历与队首元素相关的边,更新他们的d[v],如果结点不在队中,那么将该结点入队,并标记!依此类推,每次拿出队首,取消标记,更新d[v],若不在队中就标记入队,直到队列为空我们就可以得出起始点到所有点的最短路径。

如何判断是否更新d[v]?

我们用当前结点u的d[u]+此边边权判断是否小于原来的d[v],如果小于更新d[v],在判断是否在队中,如果在不入队,不在则入队!

顺序问题

先判断是否更新d[v]–>如果更新d[v]–>判断是否在队列–>不在入队!
(不管v点在不在队列,只要d[v]>d[u]+此边边权就更新)

实现代码:

void spfa(int start)
{
   
   
    d[start]=0;
    vis[start]=1;//标记入队
    queue<int> q;
    q.push(start);
    while(!q.empty())
    {
   
        int t=q.front();
        q.pop();
        vis[t]=0;//出队取消标记
        //遍历与u点相邻结点
        for(int i=0;i<M[t].size();i++)
        {
   
            edge e=M[t][i];
            if<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值