首页 > 编程语言 >SPFA算法

SPFA算法

时间:2024-04-19 11:27:15浏览次数:22  
标签:tmp cnt int 算法 SPFA edge 节点 dis

单源最短路算法,可以处理负边权,平均时间复杂度\(O(kn)\),最坏时间复杂度\(O(mn)\)

问题描述:

有一个连通图\(G=(V,E)\),连接节点\(i\)和节点\(j\)的边权写作\(e^i_j\)(\(e^i_j\geq 0\)),求从起点(\(s, s\in V\))开始,到其它各个节点(\(d, d\in V-s\))的最短路长度。

思路详解:

设从起点s到节点d的最短路用\(dis[d]\)表示,当然一开始除了\(dis[s]\),都初始化为无穷大。
我们要做的事情就是在搜索整张图的时候,不断更新\(dis\)。
假设我们在BFS这张图,现在有从节点\(i\)到节点\(j\)的边\(e^i_j\),那么\(dis[j]=min(dis[j], dis[i]+e^i_j)\)。
需要注意的是,如果\(dis[j]\)更新了,那么以\(j\)为起点的图连通分支的\(dis\)都是有可能要改变的。
所以需要把\(j\)节点重新放进BFS的队列中,以便尝试更新以\(j\)为起点的图连通分支的\(dis\)。这就是SPFA的核心思想!
如果图里面出现了负环,那么这个环上节点的\(dis\)就会不断地更新。
所以我们只需要对每个节点d定义一个计数器,用来统计从起点s到节点d这条路上\(dis\)的更新次数(也可以理解为s到d的最短路边数),如果更新次数大于n-1(一共n个点),那么可以断定有负环了。
当然还有一种效率较低的方法,那就是判断节点的入队次数,这里就不多介绍了。

SPFA和Dijkstra的一个显著区别是:SPFA会重复搜索一些节点,而Dijikstra的搜索过程没有重复。
Dijikstra贪心地每次取距离最小的节点进行更新,并且不会更新已经更新过的节点,要保证正确性就必须要求边权不为负。
SPFA则会更新已经更新过的节点,所以对边权没有要求,自然其时间复杂度也会更高。

模板题目参考:洛谷P3385

代码参考:

#include <bits/stdc++.h>

const int maxN = 100005, maxM = 500005;

struct Edge
{
	int to, dis, next;
}edge[maxM];

int head[maxN], cnt;

inline void add_edge(int u, int v, int d)
{
	cnt++;
	edge[cnt].dis = d;
	edge[cnt].to = v;
	edge[cnt].next = head[u];
	head[u] = cnt;
}

std::queue<int> nd;

int dis[maxN], cost[maxN];
bool vis[maxN];

bool spfa(int n)
{
	dis[1] = 0;
	nd.push(1);
	vis[1] = true;
	while (!nd.empty())
	{
		int tmp = nd.front();
		nd.pop();
		vis[tmp] = false;
		for (int i = head[tmp]; i; i = edge[i].next)
		{
			int y = edge[i].to;
			if (dis[tmp] + edge[i].dis < dis[y])
			{
				dis[y] = dis[tmp] + edge[i].dis;
				cost[y] = cost[tmp] + 1;
				if (cost[y] >= n)
					return false;
				if (!vis[y])
				{
					nd.push(y);
					vis[y] = true;
				}
			}
		}
	}
	return true;
}

标签:tmp,cnt,int,算法,SPFA,edge,节点,dis
From: https://www.cnblogs.com/Cnoized/p/18145384

相关文章

  • yolo,rcnn,fastrcnn,ssd等算法有的区别
    chatgpt回答:YOLO(YouOnlyLookOnce),RCNN(Region-basedConvolutionalNeuralNetworks),FasterR-CNN,SSD(SingleShotMultiBoxDetector)等算法都是用于目标检测的经典算法,它们在实现目标检测任务时有一些区别。YOLO:YOLO是一种单阶段(single-stage)目标检测算......
  • 第五节 极限运算法则
    第五节极限运算法则  本节讨论极限的求法,主要是建立极限的四则运算法则和复合函数的极限运算法则,利用这些法则,可以求某些函数的极限定理1:两个无穷小的和是无穷小。  用数学归纳法可证:有限个无穷小之和也是无穷小定理2:有界函数与无穷小的乘积是无穷小.  推论1:常......
  • KMP算法
    KMP算法KMP算法的核心思想是利用模式串自身的特性,在匹配过程中尽量避免回溯,以提高匹配的效率。它通过构建一个部分匹配表(也称为next数组),来指导匹配过程中模式串的移动位置,从而减少不必要的字符比较。KMP算法的基本步骤1.构建部分匹配表(next):遍历模式串,对于每个位置i,找出以......
  • good-turning算法
    解答:合并验证集与训练集,计算合并之和的数据集在训练集中出现的次数:张三喜欢外出旅行李四登山王五不喜欢12211100那么:r012N(r)242根据公式计算可以得到:r*r(0)=2r(1)=1r(2)=2N(r*)242(最高次数的N(r*)不变的)那么......
  • 边缘计算智能分析网关V4地面垃圾AI检测算法介绍及场景应用
    在传统的卫生监管场景中,无法及时发现地面遗留的垃圾,通过人工巡逻的方式需要大量的人力、物力和时间,而且效率不高,并存在一定的滞后性,而采用地面垃圾AI检测算法则可以大大提高监管效率。TSINGSEE青犀AI智能分析网关V4的地面垃圾AI检测算法可以自动识别划定区域内遗留的垃圾,若达到设......
  • TSINGSEE青犀算法中台消防通道堵塞/占压AI检测算法的介绍及应用
    消防通道是建筑物内用于紧急疏散的通道,其畅通无阻对于保障人员生命安全至关重要。然而,由于各种原因,消防通道经常会被杂物、车辆等堵塞,一旦发生火灾等紧急情况,后果不堪设想。为了有效解决这一问题,我们提出了一种基于人工智能技术的消防通道堵塞占用检测算法。该算法利用深度学习技......
  • 30天【代码随想录算法训练营34期】第七章 回溯算法part06 (● 332.重新安排行程 ● 51
    332.重新安排行程木有看懂,没视频所以也没看懂51.N皇后自己写出来还是有难度的classSolution:defsolveNQueens(self,n:int)->List[List[str]]:result=[]#存储最终结果的二维字符串数组chessboard=['.'*nfor_inrange(n)]#初始化......
  • Dijkstra算法
    单源最短路算法,不能处理负环,朴素版时间复杂度\(O(n^2)\),堆优化版时间复杂度\(O(nlogn)\)。Dijkstra算法的流程是:将所有的节点分为A、B的两个集合,一开始A集合中只有起点,其他的节点在B集合。定义B中的节点与A的距离:若邻接A中的结点,则距离为边权;反之距离无穷大。1.找到与A距离最小......
  • 基于深度学习的停车场车辆检测算法matlab仿真
    1.算法运行效果图预览   上图测试结果如下图所示:   2.算法运行软件版本matlab2022a 3.算法理论概述     随着城市交通管理和智慧停车系统的快速发展,停车场车辆检测已成为实现高效车位管理、智能计费的关键技术之一。深度学习,尤其是基于卷积神经网络(CN......
  • 数据结构与算法
    1数据结构1.1动态数组①数组特点存储特点:连续存储优点:查找块,访问元素快缺点:插入、删除元素效率低②实现思路1.初始化:malloc()动态分配内存区域2.扩展长度:realloc()重新调整内存区域大小3.插入元素:插入位置,后面所有元素后移4.删除元素:删除位置,后面所有元......