SPAF

本文深入讲解了Bellman-Ford算法的优化版本——SPFA算法,通过引入队列机制减少无意义操作,有效提升寻路算法效率。介绍了SPFA算法的工作原理、伪代码及实现细节,适合对图算法和路径寻找感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虽然Bellman-Ford 算法的思路很简洁,但是O(VE)的复杂度很高,然后怎么办呢?优化嘛,Bellman-Ford 算法的每轮操作都需要操作所有边,显然这个其中会有大量无意义的操作,严重影响算法性能,

只有当某个顶点u的 d[u]改变时,从它出发的边的邻接点v 的d[v]才有可能改变

是不是想到了什么???对了就是队列。

我们建立一个队列,每次将队首的顶点元素u取出,然后对u出发的所有边都松弛一遍,就是判断 d[u]  + length[ u->v ] < d[v] 是否成立,如果成立就用 d[u]  + length[ u->v ] 覆盖 d[v] 于是d[v]获得更优值。如果v不在队列中就加入队列,这样操作指导队列为空(说明图中没有从源点可达的负环),或是某个顶点的入队次数超过V - 1(说明图中存在从源点可达的负环)

伪代码

queue<int> Q;
源点入队 
while(队列非空){
	取出队首元素u;
	for(u的所有邻接边u->v){
		if(d[u] + dis < d[v]){
			d[v] = dis + d[u];
			if(v 当前不在队列里){
				v入队;
				if(v入队次数大于n-1){
					说明有可达的负环, return ; 
				} 
			} 
		}
	} 
}

优化后的算法叫SPFA,期望时间复杂度为O(kE)E为边数,k是常数,如果有负环,退化为O(VE).

vector<Node> Adj[MAXV];
int n, d[MAXV], num[MAXV];
bool inq[MAXV];

bool SPFA(int s) {
	memset(inq, false, sizeof(inq));
	memset(num, 0, sizeof(num));
	fill (d, d + MAXV, INF);
	queue<int> Q;
	Q.push(s);
	inq[s] = true;
	num[s] ++;
	d[s] = 0;
	while(!Q.empty()){
		int u = Q.front();
		Q.pop();
		inq[u] = false;
		for(int j = 0; j < Adj[u].size(); j++){
			int v = Adj[u][j].v;
			int dis = Adj[u][j].dis;
			if(d[u] + dis < d[v]){
				d[v] = d[u] + dis;
				if(!inq[v]){
					Q.push(v);
					inq[v] = true;
					num[v] ++;
					if(num[v]  >= n) return false;
				}
			} 
		} 
	}
	return true;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值